我有一个与休眠注释映射的User对象,效果很好。

例如

@Entity
public class User implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long userId;

   etc ..
}


然后,我使用Spring 3 MVC创建了一个“添加用户”表单,并且我需要一个命令对象来支持该表单,因此我在UserCommand中从上面将User子类化。 UserCommand上有一些与Web界面等相关的额外内容,不需要另存为User实体的一部分。

例如

public class UserCommand extends User {

    private String initialAddress;

    etc
}


因此,我的视图/表示层基本上创建了一个UserCommand对象,填写了用户详细信息,然后控制器将其提交到服务/ dao层以持久化。由于UserCommand扩展了用户(“ is-a”),因此dao接受UserCommand实例,并通过dao验证检查(例如,确保已填写用户名和密码)。

但是,当休眠实际上将对象作为数据库中的一个实体持久化时,似乎意识到实际的对象是一个UserCommand,它不是一个映射的实体,即使它是超类型的。

产生的错误是;

   org.hibernate.MappingException: Unknown entity: com.example.UserCommand
       org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:691)
       org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1494)
       org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:202)
       org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:531)
       org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:102)
       org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
       org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
       org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
       org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)


有没有办法解决这个问题?我似乎很容易做,表单正在填写一个User,因此只需使用User的扩展名(即UserCommand)作为表单的后备命令对象。

还是我将不得不中断继承,在UserCommand中复制User的字段,并在提交表单期间将UserCommand中的所有值显式复制到User中?

最佳答案

我认为混合数据库和视图实体是一种不好的做法。这些是不同的层,它们应在不同的DTO上运行。通常,我使用以下模式在两层之间进行转换:

public class UserCommand {
    public static UserCommand fromUser(User user) {
        UserCommand command = new UserCommand();
        // fill UserCommand fields
        return command;
    }

    public void toUser(User user) {
        // fill User fields
    }
}


如果视图DTO和数据库DTO之间的转换需要一些复杂的逻辑,则可以将这些方法移至转换服务。

拆分这些实体的一个好处是验证。您可以指定JSR-303批注来验证这些bean,并且在大多数情况下,它们对于UI和DB而言将有所不同。

09-05 11:50