14

I am new to hibernate. What I am trying to do is use @CollectionIdto generate an identifier for my Address class. I have used Collection interface for this. However when I use @GenericGenerator and set strategy to hilo, it throws an Exception. Here's my code:

@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;
    }
}

I get the following exception:

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

I am using the latest hibernate. What should I do?

Benoît
  • 1,080
  • 11
  • 28
Aditya Sawant
  • 315
  • 4
  • 13

7 Answers7

33

Hilo is not supported anymore, this should work

@GenericGenerator(name="sequence-gen",strategy="sequence")
Avinash Mishra
  • 498
  • 4
  • 9
12

If we are using mysql it would be better to use the @GenericGenerator of increment strategy.

  1. sequence - This sort of strategy supports by Oracle, Postgresql.
  2. increment - This sort of strategy supports by 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<>();
    

When I have used the sequence strategy with MySql I came across an issue where my ADDRESS_ID is not getting incremented properly.

SEQUENCE_STRATEGY_ISSUE

Gaurav Pathak
  • 2,576
  • 1
  • 10
  • 20
  • 1
    Thanks for this information it is quit helpful, i too was getting the error but not the above one, my code refused to compile with below error- org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists sequence-gen" via JDBC Statement. But modifying strategy to increment resolved the issue. – Rajan Chauhan Apr 18 '20 at 16:50
1

The Support for 'hilo' generator has been removed. For additional information, this link gives you the deprecated list.

To overcome this, you can simply use sequence generator. This will solve your problem.

@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;
    }
}
Du-Lacoste
  • 11,530
  • 2
  • 71
  • 51
1

FYI, MYSQL supports sequence strategy however table name should not contain hyphen '-' (which is name provided in @GenericGenerator(name) could cause DDL exception while creating sequence table in mysql.

1

This is what works for apps on PostgreSQL. Though I have not tested it, it should work for all DBs. Note that increment-gen is used not sequence.

@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>();
ken4ward
  • 2,246
  • 5
  • 49
  • 89
0

You must choose from one of the Hi/Lo strategy :

To be as close as your tutorial as possible, I would simply change "hilo" to "seqhilo" in your code.

Benoît
  • 1,080
  • 11
  • 28
0

I would recommend you to try any of the below 2 solutions and it will fix your issue. it is as per the specification provided in Hibernate 5.2.X.

Source Of Info -https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html

Solution 1 -

 @GenericGenerator(name = "product_generator",strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator")
 @CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*

Solution 2 -

*@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "product_generator")
 @CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "product_generator", type = @Type(type="long"))*

Let me know if it helps you.

  • Can you explain what is the source of the problem and how your three lines fix it? – Dayron Gallardo Sep 20 '18 at 19:49
  • 1
    The source of the problem is Aditya Sawant was trying to use Hilo strategy in hibernate. Which is deprecated in newer versions of hibernate. My 2 solution advises on how to achieve the same goal using the Generic Generator of SEQUENCE type. – Punit Singh Sep 21 '18 at 19:49