2014-10-27 93 views
0

我有兩個天然ID標識用戶實體,像休眠 - byNaturalId不工作

@Entity 
@Table(name = "user", uniqueConstraints = 
{ @UniqueConstraint(columnNames = "email"), 
    @UniqueConstraint(columnNames = "nick") }) 
public User() 
{} 

@Id 
@GeneratedValue(strategy = IDENTITY) 
@Column(name = "id", unique = true, nullable = false) 
private id; 

@Column(name = "email", unique = true, nullable = false, length = 31) 
@NaturalId(mutable = true) 
private String email; 

@Column(name = "nick", unique = true, nullable = false, length = 31) 
@NaturalId(mutable = false) 
private String nick; 

然而,當我嘗試執行

session.byNaturalId(User.class).with(LockOptions.READ).using("email", "[email protected]").load(); 

它拋出一個異常

org.hibernate.HibernateException: Entity [pervasive.com.gmail.tigerjack89.forum.shared.model.entities.User] defines its natural-id with 2 properties but only 1 were specified 
at org.hibernate.event.spi.ResolveNaturalIdEvent.<init>(ResolveNaturalIdEvent.java:75) 
at org.hibernate.event.spi.ResolveNaturalIdEvent.<init>(ResolveNaturalIdEvent.java:52) 
at org.hibernate.internal.SessionImpl$BaseNaturalIdLoadAccessImpl.resolveNaturalId(SessionImpl.java:2607) 
at org.hibernate.internal.SessionImpl$NaturalIdLoadAccessImpl.load(SessionImpl.java:2722) 
at pervasive.com.gmail.tigerjack89.forum.server.model.orm.StorageManager.getByNaturalId(StorageManager.java:217) 
at pervasive.com.gmail.tigerjack89.test.local.MyHibernateTest.test1(MyHibernateTest.java:37) 
at pervasive.com.gmail.tigerjack89.test.local.MyHibernateTest.main(MyHibernateTest.java:23) 

這是爲什麼?我認爲這也是由於Hibernate生成的SQL語法的日誌。事實上,奇怪的是(冗餘)在這一點上,我認爲這是異常

Hibernate: 
    alter table user 
     add constraint UK_t8tbwelrnviudxdaggwr1kd9b unique (email, nick) 
Hibernate: 
    alter table user 
     add constraint UK_ob8kqyqqgmefl0aco34akdtpe unique (email) 
Hibernate: 
    alter table user 
     add constraint UK_pvnbxcfihb58o5n2n1fnc7fh1 unique (nick) 

編輯的原因:再次讀碼,我認爲這個問題可能涉及到@UniqueConstraints註釋。但是,即使我嘗試刪除其中的一個,Hibernate仍會繼承上述SQL語法。

+0

你能告訴我們你是路過的使用'()'在你的代碼的方法值有一些更詳細:' session.byNaturalId(User.class).with(LockOptions.READ).using(attributeName,value).load();'?這將有助於查看「attributeName」和「value」是什麼。 – 2014-10-27 16:35:19

+0

基本上,你告訴休眠你的NaturalId是電子郵件和暱稱的組合。所以你必須在查詢中傳遞這兩個屬性的值。 – John 2014-10-27 16:36:17

+0

@RicardoPerezHernando當然,我錯過了:) – tigerjack89 2014-10-27 16:37:51

回答

0

我會使電子郵件地址單獨NaturalId,然後您的查詢將工作。

當兩列標識爲NaturalId時,它會創建一個Composite Key。

尼克仍然可以用作外鍵。

0

你有一個複合naturalId鍵(電子郵件,尼克),所以你可以有簡單的電子郵件參數的多個結果。 你已經使用

session 
    .byNaturalId(User.class) 
    .with(LockOptions.READ) 
    .using("email", "[email protected]") 
    .using("nick", "admin") 
    .load(); 

您還可以使用元模型

session 
    .byNaturalId(User.class) 
    .with(LockOptions.READ) 
    .using(User_.email.getName(), "[email protected]") 
    .using(User_.nick.getName(), "admin") 
    .load();