How create a constraint with Hibernate? - java

How can I create a constraint with Hibernate? I'm mapping two classes, "Team" and "Match", but I want that a match JUST can happens if the teams are from the same League. The way that I'm doing right now I can create a match with teams from differents leagues (which isn't interesting in this case).
Is there some annotation that "wraps" my teams, home and away, just being from one league? Or I have to do this in my system?
Thanks.
#Table(name = "match")
#Entity
public class Match implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToOne
#JoinColumn(name = "id_league")
private League league;
#ManyToOne
#JoinColumn(name = "id_home", referencedColumnName="id")
private Team home;
#ManyToOne
#JoinColumn(name = "id_away", referencedColumnName="id")
private Team away;
#Column
private Integer goalsHome;
#Column
private Integer goalsAway;
#Temporal(value = TemporalType.DATE)
private Date matchDate;
and
#Table(name="team")
#Entity
public class Team implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(length = 55)
private String name;
#ManyToOne
#JoinColumn(name = "id_league")
private League league;
#OneToMany
private List<Match> match;

Related

Making primary key same as foreign key in Hibernate entity

I am new to Hibernate. I am working on two entities as follows:
Entity 1 is as follows:
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#OneToOne
#JoinColumn(unique = true)
private User user; <--- HOW WILL I DENOTE THIS PRIMARY KEY OF VMUSER ENTITY ?
In the associated table in mysql i.e. vm_user, user_id is both primary key as well as foreign key which refers to id of user table associated with User entity.
Entity 2 is as follows:
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#ManyToOne
private A a;
#OneToOne
#JoinColumn(unique = true)
private B b;
In the associated table in mysql i.e. my_entity, primary key is a combination of id of a and id of b. I am not getting how to denote this in Hibernate entity MyEntity.
Regarding the same, I have gone through a few posts: Hibernate foreign key as part of primary key and JPA & Hibernate - Composite primary key with foreign key, but no getting idea how to do these two ?
The solution is #MapsId
For example
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
#Id
#Column(name = "user_id")
private Integer id;
#MapsId
#OneToOne
private User user;
You can also remove the #JoinColumn(unique = true) because #Id makes it unique already.
public class MyEntityPk implements Serializable {
private Integer aId;
private Integer bId;
// IMPORTANT: Override equals() and hashCode()
}
#IdClass(MyEntityPk.class)
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
#Id
private Integer aId;
#Id
private Integer bId;
#MapsId("aId")
#ManyToOne
private A a;
#MapsId("bId")
#OneToOne
private B b;
Please find more information in the Hibernate documentation https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers-derived
You need to use #EmbeddedId and #MapsId ,
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
#Id
#Column(name = "user_id")
private Integer id;
#MapsId("user_id")
#OneToOne
private User user;
}
You can do the same thing for MyEntity as below,
#Embeddable
class BKey {
private int aId;
private int bId;
}
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
#EmbeddedId
private BKey primaryKey;
#MapsId("aId")
#ManyToOne
private A a;
#MapsId("bId")
#OneToOne
#JoinColumn(unique = true)
private B b;
}
VM Users class
public class VmUser implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#OneToOne
#JoinColumn(name="ID")
private Users user;
Users class
public class Users implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#OneToOne(mappedBy="user")
private VmUser vmUser;
A class
#Entity
public class A implements Serializable {
#Id
private long id;
#OneToMany(mappedBy="a")
private List<MyEntity> myEntitys;
B Class
#Entity
public class B implements Serializable {
#Id
private long id;
#OneToMany(mappedBy="b")
private List<MyEntity> myEntitys;
MyEntity class
#Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private MyEntityPK id;
#ManyToOne
#JoinColumn(name="ID1")
private A a;
#ManyToOne
#JoinColumn(name="ID2")
private B b;
MyEntityPK class
#Embeddable
public class MyEntityPK implements Serializable {
#Column(insertable=false, updatable=false)
private long id1;
#Column(insertable=false, updatable=false)
private long id2;

JPA HIBERNATE - mapping a column twice (embeddedID and POJO)

I have to map a badly designed DB. And in the class "cote" there a composed PK with FK fields. So i made an embeddedable to avoid using derived entities with IdClass. So I tried this :
#Entity
#Table(name="EVA_COTE")
public class Cote implements Serializable{
/**
*
*/
private static final long serialVersionUID = -3902534586060936635L;
#EmbeddedId
private CotePK cotePK;
#ManyToOne
#JoinColumn(name="Evaluation", referencedColumnName = "NUDOSS")
private Evaluation evaluation;
#ManyToOne
#JoinColumn(name="CRITERE", referencedColumnName = "CODE")
private Critere critere;
#ManyToOne
#JoinColumn(name="SEUIL", referencedColumnName = "CODE")
private Seuil seuil;
#Column(name="VALEUR", columnDefinition="Decimal(5,0)")
private Integer valeur;
#Column(name="OBSERVATIONS", length=500)
private String observations;
With the following EmbeddedId :
#Embeddable
public class CotePK implements Serializable{
/**
*
*/
private static final long serialVersionUID = 6835265195560184935L;
#Column(name="Evaluation", nullable=false)
private Integer evaluationId;
#Column(name="CRITERE", nullable =false)
private String critereId;
#Column(name="SEUIL", nullable=false)
private String seuilId;
As you can see i use the columns evaluation critere and seuil once in the embeddedId and once in the class Cote. And of course it doesn't work and i don't know what to try anymore. Is there a way to force JPA to link the two fields?
My final solution :
#Entity
#Table(name="EVA_COTE")
public class Cote implements Serializable{
/**
*
*/
private static final long serialVersionUID = -3902534586060936635L;
#EmbeddedId
private CotePK cotePK;
#ManyToOne
#MapsId("evaluationId")
#JoinColumn(name="EVALUATION", referencedColumnName = "NUDOSS")
private Evaluation evaluation;
#ManyToOne
#MapsId("critereId")
#JoinColumn(name="CRITERE", referencedColumnName = "CODE")
private Critere critere;
#ManyToOne
#MapsId("seuilId")
#JoinColumn(name="SEUIL", referencedColumnName = "CODE")
private Seuil seuil;
Add this annotation to composite primary key
#EmbeddedId
#AttributeOverrides( {
#AttributeOverride(name="column_varible_name_1", column=#Column(name="column_name_1", nullable=false, length=<x>) ),
#AttributeOverride(name="column_varible_name_2", column=#Column(name="column_name_2", nullable=false, length=<x>) ) } )

JPA : OneToMany, get set of children of the owner entity

I have those two entities :
#Entity
#Table(name = "commande")
public class Commande implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "name")
private String name;
#OneToMany(mappedBy = "commande")
#JsonIgnore
private Set<Piece> pieces = new HashSet<>();
#Entity
#Table(name = "piece")
public class Piece implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "ref")
private String ref;
#ManyToOne
private Commande commande;
When I load the entity Commande, I would like its property pieces not to be empty if there are pieces linked to this commande.
How can I achieve that?
Thank you.

Hibernate Many-to-many with extra column do not insert children

I have an issue with my Hibernate app,
I have model as below:
Team.java
#Entity
#Table(name = "TEAM")
public class Team implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "antony", strategy = "increment")
#GeneratedValue(generator = "antony")
#Column(name = "TEAM_ID")
int id;
#Column(name = "TEAM_NAME")
String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.team")
#Column(name="TEAM_ID")
private Set<TeamMatchReference> teamMatchs = new HashSet<TeamMatchReference>(0);
Match.java
#Entity
#Table(name = "MATCHS")
public class Match implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "antony", strategy = "increment")
#GeneratedValue(generator = "antony")
#Column(name = "MATCH_ID")
int id;
//........
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.match")
#Column(name="MATCH_ID")
private Set<TeamMatchReference> teamMatchs = new HashSet<TeamMatchReference>(0);
TeamMatchId.java
#Embeddable
public class TeamMatchId implements Serializable {
private static final long serialVersionUID = 1L;
#ManyToOne
private Team team;
#ManyToOne
private Match match;
TeamMatchReference .java
#Entity
#Table(name = "team_match_reference")
#AssociationOverrides({
#AssociationOverride(name = "pk.team", joinColumns = #JoinColumn(name = "TEAM_ID")),
#AssociationOverride(name = "pk.match", joinColumns = #JoinColumn(name = "MATCH_ID")) })
public class TeamMatchReference implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private TeamMatchId pk;
#Column(name = "BET")
private float bet;
#Column(name = "SCORE")
private Integer score;
Then, I try to add new or update an Match object. The match was updated but its children - TeamMatchReference - were not updated, they're not inserted or deleted when I add or remove from the match.teamMatchReferenceSet.
Please help to make my code will update - insert and delete - the children when I update and save the match object.
You need to use cascade
#OneToMany(cascade={CascadeType.ALL})
There are different cascade type. You can select the one that fits your requirement.

JPA OneToMany, ManyToOne bidirectional

I'm trying to get rid of the following error:
The attribute [lcritical] in entity
class [class
pl.pwc.docs.pl704.PL704_Error] has a
mappedBy value of [pl704_error] which
does not exist in its owning entity
class [class
pl.pwc.docs.pl704.PL704_Error_Critical].
If the owning entity class is a
#MappedSuperclass, this is invalid,
and your attribute should reference
the correct subclass.
PL704 #Entity class:
#Entity
public class PL704 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private int Status;
private String Comments;
#OneToMany(mappedBy="pl704", cascade=CascadeType.ALL, targetEntity=PL704_Error.class, fetch=FetchType.EAGER)
private Collection lerror = new ArrayList<PL704_Error>();
//getters, setters...
PL704_Error #Entity class:
#Entity
public class PL704_Error implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String ErrorType;
private String ErrorReason;
private String ErrorLocation;
private String OriginalAttributeValue;
#ManyToOne
#JoinColumn(name = "PL704_ID", referencedColumnName = "ID")
private PL704 pl704;
#OneToMany(mappedBy="pl704_error", cascade=CascadeType.ALL, targetEntity=PL704_Error_Critical.class, fetch=FetchType.EAGER)
private Collection lcritical = new ArrayList<PL704_Error_Critical>();
//getters, setters...
PL704_Error_Critical #Entity class:
#Entity
public class PL704_Error_Critical implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name = "PL704_ERROR_ID", referencedColumnName = "ID")
private PL704_Error error;
//getters, setters...
Summing up, One PL704 can have many PL704_Error. One PL704_Error can have many PL704_Error_Critical.
How should I change my code to fix an error?
Used: EclipseLink 2.1.1, H2 Embedded.
It should be
#OneToMany(mappedBy="error", cascade=CascadeType.ALL,
targetEntity=PL704_Error_Critical.class, fetch=FetchType.EAGER)
private Collection lcritical = new ArrayList<PL704_Error_Critical>();
look at the corresponding property name in PL704_Error_Critical:
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name = "PL704_ERROR_ID", referencedColumnName = "ID")
private PL704_Error error;
The mapped by attribute spelling is not correct, maybe this is the cause:
In class PL704_Error the lcritical attribute is reversed mappedBy Attribute
#OneToMany(mappedBy="pl704_error"...
But the variable in PL704_Error_Critical is called only error.

Categories

Resources