Assume you don't mind the mixture of Hibernate and JPA Annotation and your JPA provider is Hibernate, which is mostly the case, a solution before JPA starts introducing new Annotation is, to replace JPA @SequenceGenerator with Hibernate @GenericGenerator. Now, let the code talk.
/** * Ordinary JPA sequence. * If the Long is changed into BigInteger, * there will be runtime error complaining about the type of primary key */ @Id @Column(name = "id", precision = 12) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XyzIdGenerator") @SequenceGenerator(name = "XyzIdGenerator", sequenceName = "xyz_id_sequence") public Long getId() { return id; }
In order to generate BigInteger primary key, a custom BigIntegerSequenceGenerator is created.
Replace the JPA @SequenceGenerator with Hibernate @GenericGenerator, where the strategy can be the class name of IdGenerator.package com.mycompany.myapp.id; import org.hibernate.id.SequenceGenerator; ... public class BigIntegerSequenceGenerator extends SequenceGenerator { @Override public Serializable generate(SessionImplementor session, Object obj) { ... } }
Customized IdGenerator is one of the features in the gap between JPA and Hibernate persistence Annotations. Similar missing features in JPA include other things like @Generated annotation in Hibernate for non-primarykey generated fields.@Id @Column(name="id", precision = 32) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XyzIdGenerator") //@SequenceGenerator(name = "XyzIdGenerator", sequenceName = "xyz_id_sequence") @GenericGenerator(name = "XyzIdGenerator", strategy = "com.mycompany.myapp.id.BigIntegerSequenceGenerator", parameters = { @Parameter(name = "sequence", value = "xyz_id_sequence") }) public BigInteger getId() { return id; }
4 comments:
Hi Jiaqi's thanks for this post.
I'm trying to implement a custom generator for JPA, (Hibernate is the JPA provider in my case), and this article turns out to be very handy. :)
I have two questions, I would appreciate very much your answers.
Is the "xyz_id_sequence" value for the sequenceName arbitrary ? How about the generator "XyzIdGenerator" value
is it arbitrary?
Also, I tried your sample and got
javax.persistence.PersistenceException: org.hibernate.MappingException: could not instantiate id generator exception.
Any ideas?
Thanks !
Paul
xyz_id_sequence is the sequence name in database. XyzIdGenerator is arbitrary, but the generator in @GeneratedValue must match name of @SequenceGenerator.
Basically it means field is a generated value, generated by a sequence type generator named "XyzIdGenerator" and @SequenceGenerator defines what "XyzIdGenerator" is, and it actually is a database sequence named "xyz_id_sequence"
Once can use @prePersist and other JPA events to create their own ids.
I think your exception is wrong
public Serializable generate(SessionImplementor session, Object obj)
throws HibernateException {
Post a Comment