JPA – Trucs et astuces

  • mettre les annotations sur les méthodes et non sur les attributs
  • chaque entité doit implémenter java.io.Serializable
  • utiliser les annotations Embeddable / Embedded pour mieux définir le domaine métier
  • utiliser des données du domaine pour implémenter equals/hashcode et non l’identifiant technique
  • visibilité du constructeur sans argument : protected
  • visibilité du setter de l’indentifiant technique : protected
  • ne pas utiliser de type primitif sur une entité
  • utiliser l’annotation Basic pour ajouter l’information optional=false par défaut
  • utiliser l’annotation Column pour maîtriser le mapping
  • utiliser l’annotation Temporal pour les types temporel
  • ne pas utiliser les types java.sql.Date et java.sql.Timestamp

JPA JoinColumn vs MappedBy

Extrait la page : http://stackoverflow.com/questions/11938253/jpa-joincolumn-vs-mappedby

@JoinColumn could be used on both sides of the relationship. The question was about using @JoinColumn on the @OneToMany side (rare case). And the point here is in physical information location.

According to documentation:

Since many to one are (almost) always the owner side of a bidirectional relationship in the JPA spec, the one to many association is annotated by @OneToMany(mappedBy=…)

@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set getSoldiers() {
...
}

@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
...
}

Troop has a bidirectional one to many relationship with Soldier through the troop property. You don’t have to (must not) define any physical mapping in the mappedBy side.

To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. This solution is not optimized and will produce some additional UPDATE statements.

@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set getSoldiers() {
...
}

@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}