What is the proper JPA mapping for @Id in parent and unique sequence in base classes
Asked Answered
P

2

9

I have a class hierarchy:

abstract DomainObject {
...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ")
    @SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME")
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
...
}

BaseClass extends DomainObject {
...
   // Fill in blank here where this class's @Id will use a unique sequence generator
   // bonus points for any sort of automatic assignment of generator names that might 
   //prevent me from having to instrument all my domain objects uniquely
...
}

notes:

  • I do not specifically need a base class generator, so if it behooves me to remove it no problem.
  • This is an oracle 9i db if that is applicable
  • Hibernate 3.4 JPA
  • Spring 2.5 is available as well

Thanks

Pectoral answered 23/6, 2009 at 13:9 Comment(0)
P
10

Okay here's how I ended up solving the problem:

Base class:

@MappedSuperclass
public abstract class DomainObject implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ")
 @Column(name = "id", updatable = false, nullable = false)
 private Long id;

 .. rest of class
}

Descendant class:

@Entity
@SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME")
public class BusinessObject extends DomainObject {

 ...

}
Pectoral answered 24/11, 2009 at 16:50 Comment(2)
I believe this would only work for your first extension of DomainObject within the same persistence unit. On the next one, where you have to set the name of SequenceGenerator to also be "SEQ" it would fail. At least that's what mine did using EclipseLink JPA provider, and according to the javadoc download.oracle.com/javaee/5/api/javax/persistence/… the name must be unique.Olds
for anyone else looking at this thread...this comment is the case for OpenJPA 2.2. You cannot overload the SequenceGenerator name.Crt
N
0

I would recommend you use the JOINED inheritance type for the base class. This puts all of the common fields in the base table and customizations in specific tables. Here is the annotation for that:

@Inheritance(strategy=InheritanceType.JOINED)

Once that is done, you can pretty much use any sequencing option as all of your IDs are always on the same table. You can use a separate sequence if you want but it is not supported in all database vendors. I guess that is not an issue since you are using Oracle specifically.

I've used this and it seems to work well.

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Near answered 23/6, 2009 at 14:0 Comment(1)
It's kind of hard to tell what Nathan's intention was from the example but I ran across this question because I'm migrating from Hibernate mappings to JPA annotations and all of my entities extend a base class so I don't have to define an id field, getter/setter, equals(), hashCode(), etc. for each class I want to persist. In my case, I'm using inheritance to reduce boilerplate code but there isn't really any inheritance going on from a data perspective. In that case, @MappedSuperclass really would be the preferred solution.Shermanshermie

© 2022 - 2024 — McMap. All rights reserved.