HiLo 生成器策略不起作用
HiLo generator strategy not working
我是休眠新手。我想做的是使用 @CollectionId
为我的地址 class 生成一个标识符。为此,我使用了 Collection
界面。但是,当我使用 @GenericGenerator
并将策略设置为 hilo 时,它会抛出异常。
这是我的代码:
@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID")
)
@GenericGenerator(name = "hilo-gen", strategy = "hilo")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "hilo-gen", type = @Type(type="long"))
private Collection<Address> address = new ArrayList<Address>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Collection<Address> getAddress() {
return address;
}
public void setAddress(List<Address> address) {
this.address = address;
}
}
我得到以下异常:
Exception in thread "main" org.hibernate.MappingException: Could not instantiate id generator [entity-name=null]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:121)
at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:259)
at org.hibernate.persister.collection.AbstractCollectionPersister.<init>(AbstractCollectionPersister.java:429)
at org.hibernate.persister.collection.BasicCollectionPersister.<init>(BasicCollectionPersister.java:57)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.hibernate.persister.internal.PersisterFactoryImpl.createCollectionPersister(PersisterFactoryImpl.java:152)
at org.hibernate.persister.internal.PersisterFactoryImpl.createCollectionPersister(PersisterFactoryImpl.java:140)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:408)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at com.hbt.HibernateTest.main(HibernateTest.java:35)
Caused by: java.lang.UnsupportedOperationException: Support for 'hilo' generator has been removed
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.getIdentifierGeneratorClass(DefaultIdentifierGeneratorFactory.java:132)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:112)
... 14 more
我正在使用最新的休眠。我该怎么办?
您必须选择 Hi/Lo 策略之一:
- SequenceHiLoGenerator : 用 Sequence
支持 Hi
- MultipleHiLoPerTableGenerator : 用 Table
支持 Hi
为了尽可能接近您的教程,我只需将您的代码中的 "hilo" 更改为 "seqhilo"。
不再支持 Hilo,这应该可以工作
@GenericGenerator(name="sequence-gen",strategy="sequence")
已删除对 'hilo' 生成器的支持。有关更多信息,此 link 为您提供了已弃用的列表。
要克服这个问题,您可以简单地使用序列生成器。这将解决您的问题。
@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID")
)
@GenericGenerator(name = "sequence-gen", strategy = "sequence")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "sequence-gen", type = @Type(type="long"))
private Collection<Address> address = new ArrayList<Address>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Collection<Address> getAddress() {
return address;
}
public void setAddress(List<Address> address) {
this.address = address;
}
}
如果我们使用mysql,最好使用@GenericGenerator的increment策略。
- sequence - Oracle、Postgresql 支持这种策略。
increment - 这种策略支持 MySql.
@ElementCollection
@JoinTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID"))
@GenericGenerator(name = "increment-gen", strategy = "increment")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "increment-gen", type = @Type(type="long"))
private Collection<Address> listOfAddress = new ArrayList<>();
当我将 sequence 策略与 MySql 一起使用时,我遇到了一个问题,我的 ADDRESS_ID
没有正确增加。
我建议您尝试以下 2 种解决方案中的任何一种,它会解决您的问题。它符合 Hibernate 5.2.X.
中提供的规范
信息来源 -https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html
解决方案 1 -
@GenericGenerator(name = "product_generator",strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*
解决方案 2 -
*@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "product_generator")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*
如果对你有帮助,请告诉我。
仅供参考,MYSQL 支持序列策略,但是 table 名称不应包含连字符“-”(@GenericGenerator(name) 中提供的名称
在 mysql 中创建序列 table 时可能导致 DDL 异常。
这适用于 PostgreSQL 上的应用程序。虽然我没有测试过它,但它应该适用于所有数据库。请注意,increment-gen
不是序列。
@ElementCollection
@JoinTable( name = "user_address", joinColumns = @JoinColumn( name = "user_id"))
@GenericGenerator(name="increment-gen",strategy="increment")
@CollectionId( columns = { @Column( name ="address_id") }, generator ="increment-gen", type =@Type( type ="long"))
private Collection<Address> listOfAddresses = new ArrayList<Address>();
我是休眠新手。我想做的是使用 @CollectionId
为我的地址 class 生成一个标识符。为此,我使用了 Collection
界面。但是,当我使用 @GenericGenerator
并将策略设置为 hilo 时,它会抛出异常。
这是我的代码:
@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID")
)
@GenericGenerator(name = "hilo-gen", strategy = "hilo")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "hilo-gen", type = @Type(type="long"))
private Collection<Address> address = new ArrayList<Address>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Collection<Address> getAddress() {
return address;
}
public void setAddress(List<Address> address) {
this.address = address;
}
}
我得到以下异常:
Exception in thread "main" org.hibernate.MappingException: Could not instantiate id generator [entity-name=null]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:121)
at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:259)
at org.hibernate.persister.collection.AbstractCollectionPersister.<init>(AbstractCollectionPersister.java:429)
at org.hibernate.persister.collection.BasicCollectionPersister.<init>(BasicCollectionPersister.java:57)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.hibernate.persister.internal.PersisterFactoryImpl.createCollectionPersister(PersisterFactoryImpl.java:152)
at org.hibernate.persister.internal.PersisterFactoryImpl.createCollectionPersister(PersisterFactoryImpl.java:140)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:408)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at com.hbt.HibernateTest.main(HibernateTest.java:35)
Caused by: java.lang.UnsupportedOperationException: Support for 'hilo' generator has been removed
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.getIdentifierGeneratorClass(DefaultIdentifierGeneratorFactory.java:132)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:112)
... 14 more
我正在使用最新的休眠。我该怎么办?
您必须选择 Hi/Lo 策略之一:
- SequenceHiLoGenerator : 用 Sequence 支持 Hi
- MultipleHiLoPerTableGenerator : 用 Table 支持 Hi
为了尽可能接近您的教程,我只需将您的代码中的 "hilo" 更改为 "seqhilo"。
不再支持 Hilo,这应该可以工作
@GenericGenerator(name="sequence-gen",strategy="sequence")
已删除对 'hilo' 生成器的支持。有关更多信息,此 link 为您提供了已弃用的列表。
要克服这个问题,您可以简单地使用序列生成器。这将解决您的问题。
@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID")
)
@GenericGenerator(name = "sequence-gen", strategy = "sequence")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "sequence-gen", type = @Type(type="long"))
private Collection<Address> address = new ArrayList<Address>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Collection<Address> getAddress() {
return address;
}
public void setAddress(List<Address> address) {
this.address = address;
}
}
如果我们使用mysql,最好使用@GenericGenerator的increment策略。
- sequence - Oracle、Postgresql 支持这种策略。
increment - 这种策略支持 MySql.
@ElementCollection @JoinTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID")) @GenericGenerator(name = "increment-gen", strategy = "increment") @CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "increment-gen", type = @Type(type="long")) private Collection<Address> listOfAddress = new ArrayList<>();
当我将 sequence 策略与 MySql 一起使用时,我遇到了一个问题,我的 ADDRESS_ID 没有正确增加。
我建议您尝试以下 2 种解决方案中的任何一种,它会解决您的问题。它符合 Hibernate 5.2.X.
中提供的规范信息来源 -https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html
解决方案 1 -
@GenericGenerator(name = "product_generator",strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*
解决方案 2 -
*@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "product_generator")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*
如果对你有帮助,请告诉我。
仅供参考,MYSQL 支持序列策略,但是 table 名称不应包含连字符“-”(@GenericGenerator(name) 中提供的名称 在 mysql 中创建序列 table 时可能导致 DDL 异常。
这适用于 PostgreSQL 上的应用程序。虽然我没有测试过它,但它应该适用于所有数据库。请注意,increment-gen
不是序列。
@ElementCollection
@JoinTable( name = "user_address", joinColumns = @JoinColumn( name = "user_id"))
@GenericGenerator(name="increment-gen",strategy="increment")
@CollectionId( columns = { @Column( name ="address_id") }, generator ="increment-gen", type =@Type( type ="long"))
private Collection<Address> listOfAddresses = new ArrayList<Address>();