2014-10-27 92 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();