我有一个由两个自然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", "admin@mail.com").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 :(得分:0)
我会将电子邮件地址单独设为NaturalId,然后您的查询就可以了。
当两列被识别为NaturalId时,它会创建一个复合键。
Nick仍然可以用作外键。
答案 1 :(得分:0)
您拥有复合的naturalId键(电子邮件,昵称),因此您可以使用简单的电子邮件arg获得倍数结果。 你使用
session
.byNaturalId(User.class)
.with(LockOptions.READ)
.using("email", "admin@mail.com")
.using("nick", "admin")
.load();
您也可以使用Metamodel
session
.byNaturalId(User.class)
.with(LockOptions.READ)
.using(User_.email.getName(), "admin@mail.com")
.using(User_.nick.getName(), "admin")
.load();