5

I have two entity classes which use generated values

@Entity
@SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")
public class Ent1 {
    @Id
    @GeneratedValue(generator = "idgen")
    private Long id;

    ...
}

@Entity
public class Ent2 {
    @Id
    @GeneratedValue(generator = "idgen")
    private Long id;

    ...
}

The problem is that if don't put the line

@SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")

on both entities I get an error:

Caused by: org.hibernate.AnnotationException: Unknown Id.generator: idgen

But the JPA spec says that the scope of the @SequenceGenerator is 'global' and can be reused across entities.

What am I missing?

Ayub Malik
  • 2,488
  • 6
  • 27
  • 42

4 Answers4

1

This seems to be a bug in the Hibernate JPA implementation because it works how you expect with EclipseLink JPA Implementation (I tested both). With Hibernate, it only worked if I declared the SequenceGenerator at the application level using an orm.xml (assuming you are using JPA EntityManager). If you don't already have an orm.xml, it goes next to your persistence.xml.

Here's an example of declaring the sequence-generator in orm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
  version="2.0">

  <sequence-generator name="idgen" allocation-size="1" initial-value="1000" />

</entity-mappings>

Then you don't have to declare the SequenceGenerator in each class.

neildo
  • 2,206
  • 15
  • 12
  • I tried adding the @SequenceGenerator to package-info.java but then I get a compiler error saying this type of annotation not applicable here. – Ayub Malik Feb 09 '14 at 13:08
  • package-info.java worked when I compiled in Eclipse, but I hadn't tried with just javac and now I see that that is not valid (funny that Eclipse allowed this). Instead you have to use orm.xml to declare the sequence-generator. See my updated answer. – neildo Feb 09 '14 at 17:10
  • would there also be a way to override the default sequencegenerator, so the generatedvalue doesn't need the explicit reference in each class? – Cloud May 02 '17 at 11:33
1

copy

@SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")

to Ent2 should work,
you can refer https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/seq-generator.html for more details

ExploreEv
  • 725
  • 8
  • 8
1

In the past, Hibernate scoped the sequences per entity and then came JPA saying that this should be global, so in order to allow both, a setting was introduced to control this. You can enable global scoping by setting hibernate.jpa.compliance.global_id_generators to true. Also see the documentation about the details: https://docs.jboss.org/hibernate/orm/5.5/userguide/html_single/Hibernate_User_Guide.html#configurations-jpa-compliance

Christian Beikov
  • 15,141
  • 2
  • 32
  • 58
  • 2
    Imporant to understand here is that this flag will enable re-using the SequenceGenerator *Definition* by making the name/config available globally. Still a _separate_ generator is created _per Entity_ (even if used on a @MappedSuperclass)!! Confusion might occur when you try to share one generator with a defined `allocationSize > 1` between multiple entites. That is not possible without rolling your own Generator AFAIK. – icyerasor Jul 15 '21 at 12:49
0

The following part of the spec is indeed strange to me.

The scope of the generator name is global to the persistence unit (across all generator types).

I would interpret it as you do: a generator can be specified at one location and reused anywhere on the same persistence unit. It's as if the current Hibernate implementation did not take this sentence into account.

Is there any JPA/Hibernate specification specialist that could help interpreting this sentence ?

Jidehem
  • 1,066
  • 11
  • 18