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;
Related
I have the class SWEntity that is central to the problem. I want set of classes SWEntityRow that is a detail of the SWEntity (one entity has many rows). The SWentity has in the key two other classes in the embeddedId Area and Procedure. When I try to map SWEntity with SWEntityRow using SWEntityRowId I take differents errors.
Some idea how I can map SWEntityRowId with SWEntity?
This is a simplified picture of the ER: https://i.stack.imgur.com/pMJzh.png
And this are my simplified classes:
SWentity
-----------
#Entity
public class SWEntity {
#EmbeddedId
private SWEntityId id;
[...]
}
SWEntityId
-------------
#Embeddable
public class SWEntityId implements Serializable{
private static final long serialVersionUID = 1L;
#NotNull
private String name;
#NotNull
private int version;
#ManyToOne
#JoinColumn(name = "areaName", nullable = false)
#JsonIgnore
private Area area;
#ManyToOne
#JoinColumn(name = "procedureName", nullable = false)
#JsonIgnore
private Procedure procedure;
}
SWEntityRow
---------------
#Entity
public class SWEntityRow{
#EmbeddedId
private SWEntityRowId sWEntityRowId;
}
SWEntityRowId
---------------
#Embeddable
public class SWEntityRowId implements Serializable {
private static final long serialVersionUID = 1L;
private String rowName;
//SWEntityId
#ManyToOne
#JoinColumns({
#JoinColumn(name="name_row", referencedColumnName="name"),
#JoinColumn(name="version_row", referencedColumnName="version"),
#JoinColumn(name="area_row", referencedColumnName="area_name"),
#JoinColumn(name="procedure_row", referencedColumnName="procedure_name"
})
}
This resolve my question
# JoinColumns({
#JoinColumn(name="entityname", referencedColumnName="name"),
#JoinColumn(name="entityversion", referencedColumnName="version"),
#JoinColumn(name="entityarea", referencedColumnName="AreaName"),
#JoinColumn(name="entityprocedure", referencedColumnName="ProcedureName")
})
The difference is in referencedColumnName="AreaName" not referencedColumnName="area_name" and the same for procedure.
Thanks!
Just one change required
#Entity
public class SWEntity {
#Id
#EmbeddedId
private SWEntityId id;
[...]
}
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;
I have the next relationship:
Currently, I have the next code:
#Embedded
public class StockPK implements Serializable {
private int storeId;
private int productId
}
#Entity
public class Stock implements Serializable {
#EmbeddedId
private StockPK id;
private int cantidad;
#ManyToOne
private Store store;
#ManyToOne
private Product product;
}
But the DDL generated (I'm using OpenJPA in TomEE) adds two aditional fields.
CREATE TABLE STOCK (
productId INTEGER NOT NULL,
storeId INTEGER NOT NULL,
quantity INTEGER NOT NULL,
PRODUCT_ID INTEGER ,
STORE_ID INTEGER ,
PRIMARY KEY (productId, storeId)
)
How should specify this relationship?
Thanks JBNizet :) — The solution was as follows:
#Embeddable
public class StockPK implements Serializable {
#Column(name = "store_id")
private int storeId;
#Column(name = "product_id")
private String productId;
// Getters, setters, hashCode, equals
}
#Entity
#Table(name = "stock")
public class Stock implements Serializable {
#EmbeddedId
private StockPK id;
#MapsId("storeId")
#ManyToOne
private Store store;
#MapsId("productId")
#ManyToOne
private Product product;
#Column(nullable = false)
private int quantity;
// Getters, setters
}
#Entity
#Table(name = "store")
public class Store implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// Other fields, getters, setters ...
}
#Entity
#Table(name = "product")
public class Product implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// Other fields, getters, setters ...
}
I'm trying to setup my entity to allow to pks. My database consist of two fields,
dealer_detail_id pk
user_detail_id pk
Both join on id in corresponding tables.
I've tried this thus far without success.
#Embeddable
public class DealerUserPk implements Serializable {
private Integer dealerDetail;
private Integer userDetail;
DealerUser
#Embeddable
#Table(name = "dealer_user", schema = "account")
public class DealerUser implements Serializable {
#EmbeddedId
private DealerUserPk id;
#Id
#ManyToOne
#JoinColumn(name = "dealer_detail_id", referencedColumnName = "id")
private DealerDetail dealerDetail;
#Id
#ManyToOne
#JoinColumn(name = "user_detail_id", referencedColumnName = "id")
private UserDetail userDetail;
DealerDetail
#Entity
#Table(name = "dealer_detail", schema = "account")
public class DealerDetail implements Serializable {
#Id
private Integer id;
UserDetail
#Entity
#Table(name = "user_detail", schema = "account")
public class UserDetail implements Serializable {
#Id
private Integer id;
Can anybody spot what I'm doing wrong?
This is correct:
#Embeddable
public class DealerUserPk implements Serializable {
private Integer dealerDetail;
private Integer userDetail;
But your DealerUser is annotated with embeddable it should be #Entity
as you are using #Table annotation.
Need to add MapsId as it follows
#Entity
#Table(name = "dealer_user", schema = "account")
public class DealerUser implements Serializable {
#EmbeddedId
private DealerUserPk id;
#MapsId("dealerDetail")
#ManyToOne
#JoinColumn(name = "dealer_detail_id", referencedColumnName = "id")
private DealerDetail dealerDetail;
#Id
#MapsId("userDetail")
#JoinColumn(name = "user_detail_id", referencedColumnName = "id")
private UserDetail userDetail;
Try with that.
Try this
#Embeddable
public class DealerUserPk implements Serializable {
#ManyToOne
private DealerDetail dealerDetail;
#ManyToOne
private UserDetail userDetail;
public void setDealerDetail(DealerDetail dealerDetail) {
this.dealerDetail=dealerDetail;
}
public DealerDetail getDealerDetail(){
return this.dealerDetail;
}
public void setUserDetail(UserDetail userDetail) {
this.userDetail=userDetail;
}
public UserDetail getUserDetail() {
return this.userDetail;
}
}
and
#Entity
#Table(name = "dealer_user")
public class ProductItem {
#Id
private DealerUserPk id= new DealerUserPk();
// --- For bidirectional association---
#SuppressWarnings("unused")
#Column(name="dealer_detail_id", nullable=false, updatable=false, insertable=false)
private Integer dealerDetail;
#SuppressWarnings("unused")
#Column(name="user_details_id", nullable=false, updatable=false, insertable=false)
private Integer userDetail;
// ---
public void setDealerDetail(DealerDetail dealerDetail) {
id.setDealerDetail(dealerDetail);
}
public DealerDetail getDealerDetail(){
return id.getDealerDetail();
}
public void setUserDetail(UserDetail userDetail) {
id.setUserDetail(userDetail);
}
public UserDetail getUserDetail() {
return id.getUserDetail();
}
}
I have a PatientVisit.java that has a one to one mapping with the PatientVisitObject.java:
#Entity
#Table(name = "P_Visit")
public class PatientVisit extends Bean {
#Id
#Column(name = "PATIENT_VISIT_SEQ")
private Long patientVisitSeq;
#Column(name = "PATIENT_FIRST_NM")
private String firstName;
#Column(name = "PATIENT_LAST_NM")
private String lastName;
#Column(name = "PATIENT_MIDDLE_NM")
private String middleName;
#OneToOne
private PatientVisitObject pvo;
}
The PatientVisitObject.java has a composite key. I need to map key.patientVisitSeq to my patientVisitSeq in the PatientVisit.java.
#Entity
#Table(name = "Patient_V_O")
public class PatientVisitObject extends Bean {
#Id
private PatientVisitObjectKey key;
#Column(name = "FIELD")
private String field;
}
Here is the key:
#Embeddable
public class PatientVisitObjectKey implements Serializable {
#Column(name = "PATIENT_VISIT_SEQ")
private Long patientVisitSeq;
#Column(name = "PATIENT_VISIT_OBJECT_SEQ")
private Long patientVisitObjectSeq;
}
I have tried using the #JoinTable annotation and cannot get it right. Could someone please give me some direction. Thanks.
You need to use bidirectional mapping with PatientVisit being the inverse side of relationship:
public class PatientVisit extends Bean {
...
#OneToOne(mappedBy = "pv")
private PatientVisitObject pvo;
...
}
public class PatientVisitObject extends Bean {
#EmbeddedId
private PatientVisitObjectKey key;
#OneToOne
#MapsId("patientVisitSeq")
private PatientVisit pv;
...
}
See also:
#MapsId