2012-12-12 44 views
0

我有一個用hibernate註釋映射的用戶對象,它工作得很好。MappingException:使用實體子類作爲命令時的未知實體

例如

@Entity 
public class User implements Serializable { 

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

    etc .. 
} 

我然後有使用Spring 3 MVC一個「添加用戶」形式和我所需的命令對象來支持這一形式,所以在子類UserCommand用戶從上方。用戶命令有一些額外的東西在網絡界面等相關,不需要保存爲用戶實體的一部分。

public class UserCommand extends User { 

    private String initialAddress; 

    etc 
} 

所以,我的看法/表示層基本上創建了一個UserCommand對象,填寫用戶信息,然後控制器提交下來到服務/ DAO層堅持。由於UserCommand擴展(「is-a」)用戶,dao接受UserCommand實例並通過dao驗證檢查(例如確保填寫了用戶名和密碼)。

然而,當hibernate實際上將對象作爲一個實體存在於數據庫中時,它似乎意識到實際的對象是一個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(即UserCommand)的擴展作爲表單的後備命令對象。

或者我將不得不打破繼承,複製UserCommand中的用戶的字段,並在表單提交時顯式複製UserCommand中的所有值到用戶?

回答

2

我認爲混合數據庫和視圖實體是一個不好的做法。這些是不同的層次,他們應該在不同的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之間的轉換需要一些複雜的邏輯,你可以將這些方法搬到轉換服務。

分解這些實體的一個好處是驗證。您可以指定JSR-303註釋來驗證這些bean,並且在大多數情況下,它們對於UI和DB而言會有所不同。

0

同意Hoaz。如果您想將對象的每個字段從DTO輕鬆複製到數據庫,則可以使用Dozer實用程序。

0

我剛剛遇到這個問題,我自己對於Hibernate 3.6可以明確定義一個子類。

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html

使用XML你可以:

<subclass name="DomesticCat" 
      discriminator-value="D"> 
    <property name="name" type="string"/> 
</subclass> 

或註釋:

@Entity @DiscriminatorValue("D") 
public class DomesticCat extends Cat { 
    //class implementation here 
} 

編輯:
不要忘了descriminator。

<discriminitor insert="false" formula="'C'" /> 

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING, insert=false) 
@DiscriminatorFormula("'C'") 
@DiscriminatorValue("C") 
public class Cat { ... } 
相關問題