Hibernate - byNaturalId不工作

问题描述 投票:0回答:2

我有一个由两个自然id标识的用户实体,类似于

@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语法。

java hibernate
2个回答
0
投票

我会将电子邮件地址单独设为NaturalId,然后您的查询就可以了。

当两列被标识为NaturalId时,它会创建一个复合键。

尼克仍然可以用作外键。


0
投票

你有一个复合的naturalId键(电子邮件,缺口),所以你可以使用简单的电子邮件arg获得多个结果。你要用

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

您也可以使用Metamodel

session
   .byNaturalId(User.class)
   .with(LockOptions.READ)
   .using(User_.email.getName(), "[email protected]")
   .using(User_.nick.getName(), "admin")
   .load();
© www.soinside.com 2019 - 2024. All rights reserved.