0

In my Java EE application that runs on GlassFish 4.1 with Derby 10.11.1.1, I am currently using the following technique to auto generate my primary keys in each of my jpa Entities:

@TableGenerator(name = "Entity1_Generator", table = "ID_Gen", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", initialValue = 0, allocationSize = 1)
@Id
@GeneratedValue(generator = "Entity1_Generator")
private Long id;

I decided yesterday that it would be nice to move the @Id to a @MappedSuperclass and then Extend the mapped superclass in each of my entities. Unfortunately, I discovered quickly that EclipseLink does not support overriding the @TableGenerator or @SequenceGenerator on subclasses. The following are a few references:

Based on this information, I came up with the following options:

  • Abandon my goal of moving the @Id to my mapped superclass. (Boo!)
  • Use a single @TableGenerator for all my entities. (Yuk!)
  • Create a custom generator by extending the EclipseLink Sequence object.
  • Abandon @GeneratedValue and create the primary keys using an EJB.

I review the following EclipseLink Custom Sequencing information but wasn't sure from the documentation that I would be able to grab distinguishing information that would allow me to create a sequence for each entity.

I am now thinking that it would be easy to create an stateless or singleton EJB that would control my sequences. I would simply remove the @GeneratedValue annotation from my code and perform the following code before persisting my entity.

myEntity.setId(idGenerator.getNextMyEntityId());

Using the IDGenerator to control my primary key generation, would have the following advantages:

  • Move @Id to mapped superclass.
  • Remove @TableGenerator from each entity.
  • Complete control over how sequences are generated.

What are the risks associated with using an EJB to create my Primary Keys?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Reed Elliott
  • 223
  • 2
  • 15
  • I'm no expert, but at least you'd have to figure out how far the sequences have gotten after a server restart. Also aren't you just moving a couple of lines of code pr. entity to the EJB instead? In case of a persistenceexception the id would now be set, but I don't know if that could be a problem – Jaqen H'ghar Apr 04 '15 at 10:21
  • Instead of using custom sequencing, you can set the sequence at the mapped superclass level and then override it in a descriptor customizer for any subclasses: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_customizer.htm With this you should be able to add any sequence to the subdescriptors. I don't have a code example handy though that shows adding a standard sequence object to a descriptor though - you may have to check for older native TopLink/EclipseLink project examples. – Chris Apr 04 '15 at 16:46
  • I compared creating entities using my IDGenerator singleton EJB versus using @TableGenerator and determined that I can create entities in about half the time with my IDGenerator. I also found a quick way to determine the last ID created if the server should crash before the IDGenerator writes the NEXT_ID to the database. Even though I am only saving myself a few lines of code in each entity, I will continue moving forward with IDGenerator since it is faster and it gives me more control over the ID creation process. – Reed Elliott Apr 06 '15 at 16:58
  • Control over the ID process is great if you need it, but with sequence preallocation, I'm not sure how your implementation can be any faster then a table sequence. – Chris Apr 10 '15 at 13:08

0 Answers0