Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Best Practice: Static Lookup Entities

Imagine, an Event entity references a Status Entity:

@Entity
@Table(name = "event")
public class Event()
{
  @Id
  @Column(name = "id", nullable = false)
  private long id;
  ...

  @ManyToOne
  @JoinColumn(name = "status_code", nullable = false)
  private Status status;
}


@Entity
@Table(name = "status")
public class Status()
{
  @Id
  @Column(name = "code", nullable = false)
  private String code;

  @Column(name = "label", nullable = false, updatable = false)
  private String label;
}

Status is mapped to a small table 'status'. Status is a typical reference data / lookup Entity.

   code  label
   ----- --------------
   CRD   Created
   ITD   Initiated
   PSD   Paused
   CCD   Cancelled
   ABD   Aborted

I'm not sure if it is a good idea to model Status as an Entity. It feels more like an enumeration of constants...

By mapping Status as an Entity, I can use Status objects in Java code, and the Status values are equally present in the database. This is good for reporting.

On the other hand, if I want to set a particular Status to an Event, I can't simply assign the constant status I have in mind. I have to lookup the right entity first:

event.setStatus(entityManager.find(Status.class, "CRD"))

Can I avoid the above code fragment? I'm affraid for a performance penalty and it looks very heavy...

  • Do I have to tweak things with read-only attributes?
  • Can I prefetch these lookup entities and use them as constants?
  • Did I miss a crucial JPA feature?
  • ...?

All opinions / suggestions / recommendations are welcome!

Thank you! J.

like image 357
Jan Avatar asked Aug 31 '10 22:08

Jan


2 Answers

You could use entityManager.getReference(Status.class, "CRD"), which might not fetch the entity from the database if it is only used to set a foreign key.

like image 130
Jörn Horstmann Avatar answered Oct 11 '22 21:10

Jörn Horstmann


Can I avoid the above code fragment? I'm affraid for a performance penalty and it looks very heavy?

Well, you could use an enum instead. I don't really see why you don't actually.

But if you really want to use an entity, then it would be a perfect candidate for 2nd level caching and this would solve your performance concern.

like image 35
Pascal Thivent Avatar answered Oct 11 '22 21:10

Pascal Thivent