eclipselink (JPA) exception: composite primary key #JoinColumn - java

OMG! i have been figuring out how to solve the following problem. I googled and tried all the possible ways, but no luck.
Caused by: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader#93dee9
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [RateProfessorPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field professorId] from the entity class [class rateprofessor.database.entity.Rating] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:115)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at rateprofessor.database.DBFactory.<clinit>(DBFactory.java:27)
... 2 more
I'm using netbeans and eclipselink (jpa 2.0).
I attach the two table structures.
For Professor Table, the name and departmentID are the composite primary key and the id is the autogenerated unique key, which is the foreign key to the rating table.
Here are the java classes for the two tables:
Professor
#Entity
#Table(name = "professor", catalog = "rateprofessor", schema = "", uniqueConstraints = {
#UniqueConstraint(columnNames = {"id"})})
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Professor.findAll", query = "SELECT p FROM Professor p"),
#NamedQuery(name = "Professor.findByName", query = "SELECT p FROM Professor p WHERE p.professorPK.name = :name"),
#NamedQuery(name = "Professor.findByDepartmentID", query = "SELECT p FROM Professor p WHERE p.professorPK.departmentID = :departmentID"),
#NamedQuery(name = "Professor.findByEmail", query = "SELECT p FROM Professor p WHERE p.email = :email"),
#NamedQuery(name = "Professor.findByPhone", query = "SELECT p FROM Professor p WHERE p.phone = :phone"),
#NamedQuery(name = "Professor.findByTitle", query = "SELECT p FROM Professor p WHERE p.title = :title"),
#NamedQuery(name = "Professor.findById", query = "SELECT p FROM Professor p WHERE p.id = :id"),
#NamedQuery(name = "Professor.findByFirstName", query = "SELECT p FROM Professor p WHERE p.firstName = :firstName"),
#NamedQuery(name = "Professor.findByLastName", query = "SELECT p FROM Professor p WHERE p.lastName = :lastName")})
public class Professor implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected ProfessorPK professorPK;
#Column(name = "email", length = 255)
private String email;
#Column(name = "phone", length = 255)
private String phone;
#Basic(optional = false)
#Column(name = "title", nullable = false, length = 255)
private String title;
#Basic(optional = false)
#Column(name = "id", nullable = false)
private int id;
#Column(name = "firstName", length = 45)
private String firstName;
#Column(name = "lastName", length = 45)
private String lastName;
#JoinColumn(name = "departmentID", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private Department department;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "professorId")
private Collection<Rating> ratingCollection;
public Professor() {
}
public Professor(ProfessorPK professorPK) {
this.professorPK = professorPK;
}
public Professor(ProfessorPK professorPK, String title, int id) {
this.professorPK = professorPK;
this.title = title;
this.id = id;
}
public Professor(String name, int departmentID) {
this.professorPK = new ProfessorPK(name, departmentID);
}
public ProfessorPK getProfessorPK() {
return professorPK;
}
public void setProfessorPK(ProfessorPK professorPK) {
this.professorPK = professorPK;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
#XmlTransient
public Collection<Rating> getRatingCollection() {
return ratingCollection;
}
public void setRatingCollection(Collection<Rating> ratingCollection) {
this.ratingCollection = ratingCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (professorPK != null ? professorPK.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Professor)) {
return false;
}
Professor other = (Professor) object;
if ((this.professorPK == null && other.professorPK != null) || (this.professorPK != null && !this.professorPK.equals(other.professorPK))) {
return false;
}
return true;
}
#Override
public String toString() {
return "rateprofessor.database.entity.Professor[ professorPK=" + professorPK + " ]";
}
}
Rating
#Entity
#Table(name = "rating", catalog = "rateprofessor", schema = "")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Rating.findAll", query = "SELECT r FROM Rating r"),
#NamedQuery(name = "Rating.findById", query = "SELECT r FROM Rating r WHERE r.id = :id"),
#NamedQuery(name = "Rating.findByDatetime", query = "SELECT r FROM Rating r WHERE r.datetime = :datetime"),
#NamedQuery(name = "Rating.findByClass1", query = "SELECT r FROM Rating r WHERE r.class1 = :class1"),
#NamedQuery(name = "Rating.findBySection", query = "SELECT r FROM Rating r WHERE r.section = :section")})
public class Rating implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id", nullable = false)
private Integer id;
#Basic(optional = false)
#Column(name = "datetime", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
private Date datetime;
#Column(name = "class", length = 45)
private String class1;
#Column(name = "section")
private Integer section;
#JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
#ManyToOne(optional = false)
private User userId;
#JoinColumn(name = "grade", referencedColumnName = "id")
#ManyToOne
private Grade grade;
#JoinColumn(name = "comment_id", referencedColumnName = "id", nullable = false)
#ManyToOne(optional = false)
private Comment commentId;
#JoinColumn(name = "professor_id", referencedColumnName = "id", nullable = false)
#ManyToOne(optional = false)
private Professor professorId;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "rating")
private Collection<RatingItem> ratingItemCollection;
public Rating() {
}
public Rating(Integer id) {
this.id = id;
}
public Rating(Integer id, Date datetime) {
this.id = id;
this.datetime = datetime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getDatetime() {
return datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
public String getClass1() {
return class1;
}
public void setClass1(String class1) {
this.class1 = class1;
}
public Integer getSection() {
return section;
}
public void setSection(Integer section) {
this.section = section;
}
public User getUserId() {
return userId;
}
public void setUserId(User userId) {
this.userId = userId;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public Comment getCommentId() {
return commentId;
}
public void setCommentId(Comment commentId) {
this.commentId = commentId;
}
public Professor getProfessorId() {
return professorId;
}
public void setProfessorId(Professor professorId) {
this.professorId = professorId;
}
#XmlTransient
public Collection<RatingItem> getRatingItemCollection() {
return ratingItemCollection;
}
public void setRatingItemCollection(Collection<RatingItem> ratingItemCollection) {
this.ratingItemCollection = ratingItemCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Rating)) {
return false;
}
Rating other = (Rating) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "rateprofessor.database.entity.Rating[ id=" + id + " ]";
}
}
Please help me. I seriously need help. Thanks you so much.

The problem is that JPA does not allow you to have a foreign keys to fields that are not the target entities id fields. In your case, Rating has a professor_id column that is a foreign key to Id, but Id is not the primary key - name and departmentID within the embeddedId are. The simplest solution is to make the ID field within Professor the ID - as far as JPA is concerned anyway. The table itself does not need to change.
This will allow you to use the professor_id as a foreign key to Professor's ID column and remain portable among JPA providers, and still use Name + departmentID as the pk in the database.

Related

Why CriteriaQuery is putting dot in hibernate string?

I have a problem with my multiselect. I'm using it as an Specification with multiple joins. I don't know why hibernate decides to put a dot in the query. the error is shown below in the query. this is the constructor I'm using
public HelperOutput(Long id,
String personName,
Long helperTypeId,
String helperTypeTitle,
String agencyTitle,
String regionalOfficeTitle,
String basketPartTitle,
YesNo allowedToOperate,
YesNo hasFlatTirePack,
Long fleetRescueId,
Long cityId,
String cityName,
Long skillLevel,
String helperRankTitle,
Long personId,
Long helperRate,
String personelId,
Long regionalOfficeId,
Long basketPartId,
String mobile,
String fleetName,
ExpertType expertType,
Long maxConcurrentWork,
Set<Long> dutyCityIds
) {
this.id = id;
this.helperTypeId = helperTypeId;
this.helperTypeTitle = helperTypeTitle;
this.agencyTitle = agencyTitle;
this.regionalOfficeId = regionalOfficeId;
this.regionalOfficeTitle = regionalOfficeTitle;
this.basketPartTitle = basketPartTitle;
this.fleetRescueId = fleetRescueId;
this.cityId = cityId;
this.helperRankTitle = helperRankTitle;
this.personId = personId;
this.basketPartId = basketPartId;
this.mobile = mobile;
this.fleetName = fleetName;
this.cityName = cityName;
this.personName = personName;
this.allowedToOperate = allowedToOperate;
this.hasFlatTirePack = hasFlatTirePack;
this.skillLevel = skillLevel;
this.helperRate = helperRate;
this.personelId = personelId;
this.expertType = expertType;
this.maxConcurrentWork = maxConcurrentWork;
this.dutyCityIds = dutyCityIds;
}
this is the multiselect which is similar to the constructor.
cq.multiselect(root.get(Helper_.ID),
personName,
helperHelperTypeJoin.get(HelperType_.ID),
helperHelperTypeJoin.get(HelperType_.TITLE),
helperAgencyJoin.get(Agency_.TITLE),
helperRegionalOfficeJoin.get(RegionalOffice_.TITLE)
, helperBasketPartJoin.get(Basket_.TITLE),
root.get(Helper_.ALLOWED_TO_OPERATE),
root.get(Helper_.HAS_FLAT_TIRE_PACK),
fleetRescueJoin.get(HelperFleet_.ID),
helperCityJoin.get(City_.ID) ,
helperCityJoin.get(City_.NAME),
root.get(Helper_.SKILL_LEVEL),
helperRankJoin.get(HelperRank_.NAME),
helperPersonJoin.get(Person_.ID),
root.get(Helper_.helperRate),
root.get(Helper_.personelId),
helperRegionalOfficeJoin.get(RegionalOffice_.ID),
helperBasketPartJoin.get(Basket_.ID),
helperPersonJoin.get(Person_.MOBILE),
HelperFleetJoin.get(Fleet_.NAME),
root.get(Helper_.EXPERT_TYPE),
root.get(Helper_.MAX_CONCURRENT_WORK),
root.get(Helper_.DUTY_CITIES)
);
this is the hibernate query which I don't know why it has a dot.
select
*
from
( select
helper0_.ID as col_0_0_,
person3_.NAME as col_1_0_,
helpertype7_.ID as col_2_0_,
helpertype7_.TITLE as col_3_0_,
agency2_.TITLE as col_4_0_,
regionalof8_.TITLE as col_5_0_,
basket6_.TITLE as col_6_0_,
helper0_.ALLOWED_TO_OPERATE as col_7_0_,
helper0_.HAS_FLAT_TIRE_PACK as col_8_0_,
helperflee4_.ID as col_9_0_,
city1_.ID as col_10_0_,
city1_.NAME as col_11_0_,
helper0_.SKILL_LEVEL as col_12_0_,
helperrank9_.NAME as col_13_0_,
person3_.ID as col_14_0_,
helper0_.HELPER_RATE as col_15_0_,
helper0_.PERSONELID as col_16_0_,
regionalof8_.ID as col_17_0_,
basket6_.ID as col_18_0_,
person3_.MOBILE as col_19_0_,
fleet5_.NAME as col_20_0_,
helper0_.EXPERT_TYPE as col_21_0_,
helper0_.MAX_CONCURRENT_WORK as col_22_0_,
. as col_23_0_ <----------- this causes the problem
from
OPR.TBL_HELPER helper0_
left outer join
OPR.TBL_CITY city1_
on helper0_.CITY_ID=city1_.ID
left outer join
TBL_AGENCY agency2_
on helper0_.AGENCY_ID=agency2_.ID
left outer join
OPR.TBL_PERSONS person3_
on helper0_.PERSON_ID=person3_.ID
left outer join
OPR.TBL_HELPER_FLEET helperflee4_
on helper0_.HELPER_FLEET_ID=helperflee4_.ID
left outer join
OPR.NOEKHODROEMDAD fleet5_
on helperflee4_.NOEKHODROEMDAD_ID=fleet5_.NOEKHODROEMDADID
left outer join
OPR.TBL_BASKET basket6_
on helper0_.BASKET_PART_ID=basket6_.ID
left outer join
OPR.TBL_HELPER_TYPE helpertype7_
on helper0_.HELPER_TYPE_ID=helpertype7_.ID
left outer join
TBL_REGIONAL_OFFICE regionalof8_
on helper0_.REGIONAL_OFFICE_ID=regionalof8_.ID
left outer join
OPR.TBL_HELPER_RANK helperrank9_
on helper0_.RANK_HELPER_ID=helperrank9_.ID
left outer join
TBL_HELPER_DUTY_CITIES dutycities10_
on helper0_.ID=dutycities10_.DUTY_CITY_ID
left outer join
OPR.TBL_CITY city11_
on dutycities10_.ESTABLISHMENT_CITY_ID=city11_.ID
inner join
TBL_HELPER_DUTY_CITIES dutycities12_
on helper0_.ID=dutycities12_.DUTY_CITY_ID
where
1=1
and 1=1
order by
helper0_.ALLOWED_TO_OPERATE asc,
person3_.NAME asc )
where
rownum <= ?
and at last I get this error when returning an Specification from the predicates I made.
Error:
2022-01-31 15:40:08.419 [http-nio-8082-exec-2] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ORA-00936: missing expression
2022-01-31 15:40:08.444 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> #AfterThrowing method: GenericRepository.findAll(..)
2022-01-31 15:40:08.445 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedMessage: ORA-00936: missing expression
2022-01-31 15:40:08.445 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedCause: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
2022-01-31 15:40:08.445 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> #AfterThrowing method: HelperServiceImpl.findByCriteria(..)
2022-01-31 15:40:08.445 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedMessage: ORA-00936: missing expression
2022-01-31 15:40:08.445 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedCause: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
2022-01-31 15:40:08.446 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> #AfterThrowing method: HelperController.show(..)
2022-01-31 15:40:08.446 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedMessage: ORA-00936: missing expression
2022-01-31 15:40:08.446 [http-nio-8082-exec-2] ERROR com.eki.opr.config.LoggingAspect - ----> detailedCause: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
EDIT
these are the entities:
#Entity(name = "HELPER")
#Table(name = "TBL_HELPER", schema = "OPR")
#EqualsAndHashCode(exclude = {"person", "agency", "helperType", "regionalOffice", "basket_part", "helperRank"})
#ToString(exclude = {"person", "agency", "helperType", "regionalOffice", "basket_part", "helperRank"})
#AllArgsConstructor
public class Helper implements Serializable {
private Long id;
#GenericGenerator(
name = "assigned-sequence",
strategy = "com.eki.opr.utils.StringSequenceIdentifier"
)
#GeneratedValue(
generator = "assigned-sequence",
strategy = GenerationType.AUTO)
private String largeId;
private Long skillLevel;
private Long currentWorkCount;
private Long maxConcurrentWork;
private YesNo allowedToOperate;
private YesNo hasGps;
private YesNo isAutoDialer;
private YesNo isPartSupply;
private YesNo hasFlatTirePack;
private String imei;
private String address;
private String personelId;
private String reservedMobile;
private Person person;
private HelperFleet helperFleet;
private HelperType helperType;
private RegionalOffice regionalOffice;
private Agency agency;
private Basket basket_part;
private Basket basket_tools;
private YesNo hasPos;
private String posSerial;
private HelperRank helperRank;
private Parameter contractType;
private Set<ServiceType> serviceTypes = new HashSet<ServiceType>();
private Long helperRate;
private ExpertType expertType = ExpertType.HELPER;
public Helper() {
}
private City city;
#JoinColumn(name = "CITY_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
private Set<HelperDutyCity> dutyCities = new HashSet<>();
/* in this part mappedBy's value should be changed to helper because the
join must be on helper not dutyCityId*/
#OneToMany(targetEntity = HelperDutyCity.class, mappedBy = "dutyCityId", fetch = FetchType.EAGER)
public Set<HelperDutyCity> getDutyCities() {
return dutyCities;
}
public void setDutyCities(Set<HelperDutyCity> dutyCities) {
this.dutyCities = dutyCities;
}
public void setHelperRate(Long helperRate) {
this.helperRate = helperRate;
}
#Column(name = "HELPER_RATE")
public Long getHelperRate() {
return helperRate;
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_helper")
#SequenceGenerator(name = "seq_helper", sequenceName = "SA.SEQ_EMDADGAR_ID", allocationSize = 1,initialValue = 63442)
#Column(name = "ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "SKILL_LEVEL")
public Long getSkillLevel() {
return skillLevel;
}
public void setSkillLevel(Long skillLevel) {
this.skillLevel = skillLevel;
}
#Column(name = "MAX_CONCURRENT_WORK")
public Long getMaxConcurrentWork() {
return maxConcurrentWork;
}
public void setMaxConcurrentWork(Long maxConcurrentWork) {
this.maxConcurrentWork = maxConcurrentWork;
}
#Column(name = "CURRENT_WORK_COUNT")
public Long getCurrentWorkCount() {
return currentWorkCount;
}
public void setCurrentWorkCount(Long currentWorkCount) {
this.currentWorkCount = currentWorkCount;
}
#Column(name = "ALLOWED_TO_OPERATE")
#Convert(converter = YesNoConverter.class)
public YesNo getAllowedToOperate() {
return allowedToOperate;
}
public void setAllowedToOperate(YesNo allowedToOperate) {
this.allowedToOperate = allowedToOperate;
}
#Column(name = "HAS_GPS")
#Convert(converter = YesNoConverter.class)
public YesNo getHasGps() {
return hasGps;
}
public void setHasGps(YesNo hasGps) {
this.hasGps = hasGps;
}
#Column(name = "PART_SUPPLY")
#Convert(converter = YesNoConverter.class)
public YesNo getIsPartSupply() {
return isPartSupply;
}
public void setIsPartSupply(YesNo isPartSupply) {
this.isPartSupply = isPartSupply;
}
#Column(name = "PERSONELID")
public String getPersonelId() {
return personelId;
}
public void setPersonelId(String personelId) {
this.personelId = personelId;
}
#Column(name = "HAS_FLAT_TIRE_PACK")
#Convert(converter = YesNoConverter.class)
public YesNo getHasFlatTirePack() {
return hasFlatTirePack;
}
public void setHasFlatTirePack(YesNo hasFlatTirePack) {
this.hasFlatTirePack = hasFlatTirePack;
}
#Column(name = "IMEI")
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
#JoinColumn(name = "CREATED_BY", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
private PersonUnion createdBy;
#Column(name = "CREATED_AT")
private LocalDateTime createdAt;
#Column(name = "IS_AUTO_DIALER")
#Convert(converter = YesNoConverter.class)
public YesNo getIsAutoDialer() {
return isAutoDialer;
}
public void setIsAutoDialer(YesNo isAutoDialer) {
this.isAutoDialer = isAutoDialer;
}
#Column(name = "RESERVED_MOBILE")
public String getReservedMobile() {
return reservedMobile;
}
#Column(name = "HAS_POS")
#Convert(converter = YesNoConverter.class)
public YesNo getHasPos() { return hasPos; }
public void setHasPos(YesNo hasPos) {
this.hasPos = hasPos;
}
#Column(name = "POS_SERIAL")
public String getPosSerial() { return posSerial; }
public void setPosSerial(String posSerial) {
this.posSerial = posSerial;
}
public void setReservedMobile(String reservedMobile) {
this.reservedMobile = reservedMobile;
}
#JoinColumn(name = "MODIFIED_BY", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
private PersonUnion modifiedBy;
#Column(name = "MODIFIED_AT")
private LocalDateTime modifiedAt;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "PERSON_ID", referencedColumnName = "ID")
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
#JoinColumn(name = "HELPER_TYPE_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public HelperType getHelperType() {
return helperType;
}
public void setHelperType(HelperType helperType) {
this.helperType = helperType;
}
#JoinColumn(name = "REGIONAL_OFFICE_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public RegionalOffice getRegionalOffice() {
return regionalOffice;
}
public void setRegionalOffice(RegionalOffice regionalOffice) {
this.regionalOffice = regionalOffice;
}
#JoinColumn(name = "AGENCY_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public Agency getAgency() {
return agency;
}
public void setAgency(Agency agency) {
this.agency = agency;
}
#JoinColumn(name = "BASKET_PART_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public Basket getBasket_part() {
return basket_part;
}
public void setBasket_part(Basket basket_part) {
this.basket_part = basket_part;
}
#JoinColumn(name = "BASKET_TOOLS_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public Basket getBasket_tools() {
return basket_tools;
}
public void setBasket_tools(Basket basket_tools) {
this.basket_tools = basket_tools;
}
#ManyToOne
#JoinColumn(name = "HELPER_FLEET_ID", referencedColumnName = "ID")
public HelperFleet getHelperFleet() {
return helperFleet;
}
public void setHelperFleet(HelperFleet helperFleet) {
this.helperFleet = helperFleet;
}
#JoinColumn(name = "RANK_HELPER_ID", referencedColumnName = "ID")
#ManyToOne(fetch = FetchType.LAZY)
public HelperRank getHelperRank() {
return helperRank;
}
public void setHelperRank(HelperRank helperRank) {
this.helperRank = helperRank;
}
#Column(name = "LARGE_ID")
public String getLargeId(){return this.largeId;}
public void setLargeId(String largeId){this.largeId = largeId;}
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "TBL_HELPER_SERVICE_TYPE", uniqueConstraints = {#UniqueConstraint(columnNames = {"HELPER_ID", "SERVICE_TYPE_ID"})},
joinColumns = #JoinColumn(name = "HELPER_ID", referencedColumnName = "ID"),
inverseJoinColumns = #JoinColumn(name = "SERVICE_TYPE_ID", referencedColumnName = "ID"))
public Set<ServiceType> getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(Set<ServiceType> serviceTypes) {
this.serviceTypes = serviceTypes;
}
#JoinColumn(name = "CONTRACT_TYPE")
#ManyToOne
public Parameter getContractType() {
return contractType;
}
public void setContractType(Parameter contractType){
this.contractType = contractType;
}
#Convert(converter = ExpertTypeConverter.class)
#Column(name = "EXPERT_TYPE")
public ExpertType getExpertType() {
return expertType;
}
public void setExpertType(ExpertType expertType) {
this.expertType = expertType;
}
public void fromDto(HelperInput input) {
this.id = input.getId();
this.address = input.getAddress();
this.allowedToOperate = input.getAllowedToOperate();
this.currentWorkCount = input.getCurrentWorkCount();
this.hasGps = input.getHasGps();
this.hasFlatTirePack = input.getHasFlatTirePack();
this.isAutoDialer = input.getIsAutoDialer();
this.personelId = input.getPersonelId();
this.isPartSupply = input.getIsPartSupply();
this.maxConcurrentWork = input.getMaxConcurrentWork();
this.hasPos = input.getHasPos();
this.posSerial = input.getPosSerial();
this.skillLevel = input.getSkillLevel();
this.reservedMobile = input.getReservedMobile();
if (input.getId() == null) { //first time
this.largeId = StringSequenceIdentifier.generateLargeId();
this.createdBy = input.getCreatedByEntity();
this.createdAt = LocalDateTime.now();
this.modifiedBy = input.getCreatedByEntity();
this.modifiedAt = createdAt;
} else {
this.modifiedBy = input.getModifiedByEntity();
this.modifiedAt = LocalDateTime.now();
}
this.helperRate = input.getHelperRate();
}
}
#Entity
#Getter
#Setter
#NoArgsConstructor
#ToString
#AllArgsConstructor
#JsonDeserialize
#Table(name = "TBL_HELPER_DUTY_CITIES")
#IdClass(HelperDutyCityKey.class)
public class HelperDutyCity implements Serializable {
#Id
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "HELPER_ID")
private Helper helper;
#Id
#OneToOne
#JoinColumn(name = "ESTABLISHMENT_CITY_ID", referencedColumnName = "ID")
#Fetch(FetchMode.JOIN)
private City establishmentCityId;
#ManyToOne
#JoinColumn(name = "DUTY_CITY_ID", referencedColumnName = "ID")
#Fetch(FetchMode.JOIN)
private City dutyCityId;
public HelperDutyCity(Helper helper, City establishmentCityId) {
this.helper = helper;
this.establishmentCityId = establishmentCityId;
}
}
#Data
#ToString(exclude = {"regions","regionalOffice", "province","productCities"})
#EqualsAndHashCode(exclude = {"regions","regionalOffice", "province","productCities"})
#JsonInclude(JsonInclude.Include.NON_NULL)
#Entity
#Table(name = "TBL_CITY", schema = "OPR")
public class City implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#GenericGenerator(
name = "seqCity",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence_name", value = "SEQ_CITY"),
#org.hibernate.annotations.Parameter(name = "initial_value", value = "100219"),
#org.hibernate.annotations.Parameter(name = "increment_size", value = "1")
}
)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqCity")
#Id
#Column(name = "ID")
private Long id;
#Column(name = "NAME")
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "PROVINCE_ID", nullable = false)
private Province province;
#GenericGenerator(
name = "assigned-sequence",
strategy = "com.eki.opr.utils.StringSequenceIdentifier"
)
#GeneratedValue(
generator = "assigned-sequence",
strategy = GenerationType.SEQUENCE)
#Column(name = "LARGE_ID")
private String largeId;
#Column(name = "OPR_SHAHR_ID")
private Double oprCityId;
#Column(name = "LATITUDE")
private Double latitude;
#Column(name = "LONGITUDE")
private Double longitude;
#Column(name = "METROPOLIS_FACTOR")
private Double metropolisFactor;
#Convert(converter = YesNoConverter.class)
#Column(name = "IS_AUTOMATED_DISPATCH")
private YesNo isAutomatedDispatch;
#Convert(converter = GeneralStatusConverter.class)
#Column(name = "STATUS")
private GeneralStatus status;
#Column(name = "PARSIMAP_CITY_CODE")
private String parsiMapCityCode;
#Column(name = "AMAR_CITY_CODE")
private String parsiMapCityAmarCode;
#JoinColumn(name = "REGIONAL_OFFICE_ID")
#ManyToOne(fetch = FetchType.LAZY)
private RegionalOffice regionalOffice;
#ManyToMany(
fetch = FetchType.LAZY, mappedBy = "cities")
Set<Region> regions = new HashSet<>();
/* #OneToMany(mappedBy = "city")
private Set<Address> addresses;*/
public City() {
}
public City(Long id) {
this.id = id;
// this.addresses = addresses;
}
public City(CityDto dto) {
fromDto(dto);
}
public void fromDto(CityDto cityDto) {
this.name = cityDto.getName();
this.metropolisFactor = cityDto.getMetropolisFactor();
}
public CityDto toDto() {
CityDto dto = new CityDto();
dto.setId(id);
dto.setName(name);
dto.setMetropolisFactor(metropolisFactor);
dto.setProvinceDto(province.toDto());
dto.setRegionalOfficeOutput(regionalOffice.toDto());
return dto;
}
public CityLite toDtoLite() {
CityLite dto = new CityLite();
dto.setId(id);
dto.setName(name);
dto.setMetropolisFactor(metropolisFactor);
dto.setProvinceId(province != null ? province.getId() : null);
dto.setProvinceName(province != null ? province.getName() : "");
dto.setRegionalOfficeId(regionalOffice != null ? regionalOffice.getId() : null);
dto.setRegionalOfficeTitle(regionalOffice != null ? regionalOffice.getTitle() : "");
dto.setParsiMapCityCode(parsiMapCityCode);
dto.setParsiMapAmarCityCode(parsiMapCityAmarCode);
dto.setLat(latitude != null ? latitude :0);
dto.setLng(longitude != null ? longitude :0);
return dto;
}
}
I answered it in a comment in Helper entity. the answer is you shouldn't make a mistake in mappedBy attribute in #OneToMany annotation. so I changed dutyCityId to helper now it's working.
before it was joining with another condition helper.ID = helperDutyCity.dutyCityId which was wrong now it joins with this condition helper.ID = helperDutyCity.helperId which is correct.

Hiberate one-to-one annotaion builds wrong sql query

I have a small problem with hibernate query with one-to-one relation
I created 3 entities. In case of one-to-one relation user-to-group it works properly. I use property create in hiberanate config and it creates correct table with correct FK.
Creating record work correct too
MyUser user = new MyUser();
user.setLogin("Mark");
user.setPassword("123456");
MyPresence presence = new MyPresence();
presence.setPresenceId(2);
presence.setUser(user);
session.beginTransaction();
session.save(user);
session.save(presence);
session.getTransaction().commit();
session.close();
if get User by presence it works correct
int id = 2;
MyPresence myPresence = session.load(MyPresence.class, id);
System.out.println(myPresence);
But when I'm try to get presence by user result from database hibernate build wrong sql query
int id = 3;
MyUser myUser = session.load(MyUser.class, id);
System.out.println(myUser);
Generated Hibernate sql:
Hibernate: select myuser0_.id as id1_2_0_, myuser0_.group_id as group_id4_2_0_, myuser0_.login as login2_2_0_, myuser0_.password as password3_2_0_, mypresence1_.id as id1_1_1_, mypresence1_.presence_id as presence2_1_1_, mypresence1_.updated_at as updated_3_1_1_, mypresence1_.user_id as user_id4_1_1_ from users myuser0_ left outer join user_presence mypresence1_ on myuser0_.id=mypresence1_.id where myuser0_.id=?
But I expect to see
on myuser0_.id=mypresence1_.user_id instead of on myuser0_.id=mypresence1_.id
MyUser.java
#Entity
#Table(name = "users")
public class MyUser {
private int id;
private String login;
private String password;
private MyGroup group;
private MyPresence presence;
public MyUser() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "login")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#JoinColumn(name = "group_id")
#OneToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
public MyGroup getGroup() {
return group;
}
public void setGroup(MyGroup group) {
this.group = group;
}
#OneToOne(cascade = CascadeType.DETACH)
#JoinColumn(name = "id", referencedColumnName = "user_id")
public MyPresence getPresence() {
return presence;
}
public void setPresence(MyPresence presence) {
this.presence = presence;
}
}
MyPresence.java
#Entity
#Table(name = "presence")
public class MyPresence {
private int id;
private MyUser user;
private int presenceId;
private Date updatedAt;
public MyPresence() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id", referencedColumnName = "id")
public MyUser getUser() {
return user;
}
public void setUser(MyUser user) {
this.user = user;
}
#Column(name = "presence_id")
public int getPresenceId() {
return presenceId;
}
public void setPresenceId(int presenceId) {
this.presenceId = presenceId;
}
#Column(name = "updated_at")
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}

How to persist entity with joining?

I am confused about how to save entry in db with column's join. I have #Entity bellow
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
public Long getBrncBrncId() {
return brncBrncId;
}
public void setBrncBrncId(Long brncBrncId) {
this.brncBrncId = brncBrncId;
}
#Column(name = "BRNC_BRNC_ID", insertable = false, updatable = false)
private Long brncBrncId;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public Long getCuratorUserId() {
return curatorUserId;
}
public void setCuratorUserId(Long curatorUserId) {
this.curatorUserId = curatorUserId;
}
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
public User() {
}
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getDef() {
return this.def;
}
public void setDef(String def) {
this.def = def;
}
public Date getDelDate() {
return this.delDate;
}
public void setDelDate(Date delDate) {
this.delDate = delDate;
}
public String getDisplayDef() {
return this.displayDef;
}
public void setDisplayDef(String displayDef) {
this.displayDef = displayDef;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getNaviDate() {
return this.naviDate;
}
public void setNaviDate(Date naviDate) {
this.naviDate = naviDate;
}
public String getNaviUser() {
return this.naviUser;
}
public void setNaviUser(String naviUser) {
this.naviUser = naviUser;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPwd() {
return this.pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Branch getPscBranch() {
return this.pscBranch;
}
public void setPscBranch(Branch pscBranch) {
this.pscBranch = pscBranch;
}
public User getPscUser() {
return this.pscUser;
}
public void setPscUser(User pscUser) {
this.pscUser = pscUser;
}
}
if I save User instance without field pscUser (here null) but there is valid CuratorUserId with correct value I end up in a situation with empty CuratorUserId in db. If you look at code then you will see these bound fields.
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
code to save user
repositoryUser.save(user);
this i see in debugger
this i see in database after saving my user.
sorry for my stupid question but I come across on a different behavior, there is code in my project which behaves in another manner. I don't want to search actual another user(curator) for saving my user, because of overhead on query
The #Column annotation on the curetorUserId field has properties
insertable=false and updatable=false, which means that its value is ignored during inserts and updates.
You can either change these properties to true (but it can break your application in some other places) or just fill in pscUser field using EntityManager.getReference, which just creates a proxy and doesn't actualy produce a query to the database.
Your mapping should look like the below:
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public User() {
}
}
You need to think in terms of objects. The FK will only be set in the database if you set the pscUser reference to an instance of a User. If this is an existing User then you need to set a reference to the existing persistent entity.
Real answer is that I have two points for saving and updating my entity. Please see this Hibernate: Where do insertable = false, updatable = false belong in composite primary key constellations involving foreign keys?

Empty List (not Table) at ManyToMany-Relation

i faced the same problem as empty tables when using many to many relations in jpa. Sadly this post was without solution. I have a class with a many-to-many relation in JPA/EclipseLink v2.6.3. Here the class ROLE:
#Entity
public class Role implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
#JoinTable(name = "ROLE_COMPETENCE", joinColumns = #JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"), inverseJoinColumns = #JoinColumn(name = "COMPETENCE_ID", referencedColumnName = "ID"))
private List<Competence> competences = new ArrayList<Competence>();
#Override
public String toString() {
return "Role [id=" + id + "]";
}
public void addCompetence(Competence competence) {
if (this.competences != null) {
if (!this.competences.contains(competence)) {
this.competences.add(competence);
competence.addRole(this);
}
}
}
public int getId() {
return id;
}
public Role() {
super();
}
public List<Competence> getCompetences() {
return competences;
}
}
And the class COMPETENCE
#Entity
public class Competence implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(length = 1024, nullable = false)
private String title;
#JsonIgnore
#ManyToMany(mappedBy = "competences", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
private List<Role> roles;
public int getId() {
return id;
}
public Competence() {
super();
}
public void addRole(Role role) {
if (this.roles != null) {
if (!this.roles.contains(role)) {
this.roles.add(role);
role.addCompetence(this);
}
}
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<Role> getRoles() {
return roles;
}
#Override
public String toString() {
return "Competence [id="+id+", title="+title+"]";
}
}
When i now use
for (int i = 0; i < 10; i++) {
Role role = new Role();
RoleService.create(role);
for (int j = 0; j < 3; j++) {
Competence c = new Competence();
c.setTitle("Competence "+i+"."+j);
CompetenceService.create(c);
lastCompetence = c;
role.addCompetence(c);
}
RoleService.update(role);
}
with
public void x(Object object) {
EntityManager em = ...
EntityTransaction tx = em.getTransaction();
tx.begin();
em.merge(object); //for x=update or em.persist(object) for x=create
tx.commit();
em.close();
}
The strange thing is that the join-table ROLE_COMPETENCE is correct when i add or remove objects. When i load ROLE's they have competences an can be shown. But the list "roles" is empty when i load competences from the database.
Any idea?
I found my mistake. It was just that the list was not instantiated. With List<Role> roles = new ArrayList<Role>(); everything works fine.

OneToMany between 2 classes with Hibernate

I'm trying to get the hang of Hibernate.
After getting my project to compile, I've started to convert my classes to be "Hibernate-enabled"
Currently, I'm having 2 classes
1) Person (id, name, firstname, ...)
2) Task (Id, name, description, idOwner)
I would like to have a OneToMany relationship between Person(id) and Task (idOwner)
So when the users gets the List from the Person class, they would get all the tasks linked to that.
After some trying and failing, here's my current code:
Person.java
#Entity
#Table(name = "people", uniqueConstraints = {
#UniqueConstraint(columnNames = "PERSON_ID")
})
public class Person implements Serializable {
private int id;
private String firstName;
private String name;
private String function;
private String email;
private String password;
private RoleEnum role;
private List<Task> lstTasks;
public Person(String firstName, String name, String function) {
this.firstName = firstName;
this.name = name;
this.function = function;
this.email = "";
this.password = "";
this.setRole(RoleEnum.User);
}
// <editor-fold defaultstate="collapsed" desc="Getters">
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "PERSON_ID", unique = true, nullable = false)
public int getId() {
return id;
}
#Column(name = "PERSON_FIRSTNAME", unique = false, nullable = false, length = 30)
public String getFirstName() {
return firstName;
}
#Column(name = "PERSON_NAME", unique = false, nullable = false, length = 30)
public String getName() {
return name;
}
#Column(name = "PERSON_FUNCTION", unique = false, nullable = false, length = 30)
public String getFunction() {
return function;
}
#Column(name = "PERSON_EMAIL", unique = false, nullable = false, length = 30)
public String getEmail() {
return email;
}
#Column(name = "PERSON_PASSWORD", unique = false, nullable = false, length = 30)
public String getPassword() {
return password;
}
#Column(name = "PERSON_ROLE", unique = false, nullable = false, length = 30)
public RoleEnum getRole() {
return role;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "idOwner")
public List<Task> getLstTasks() {
return lstTasks;
}
//Setters
}
Task.java
#Entity
#Table(name="tasks", uniqueConstraints =
#UniqueConstraint(columnNames = "TASK_ID"))
public class Task implements Serializable {
private int id;
private String name;
private String description;
private int idOwner;
public Task(int id, String name, int idOwner) {
this.id = id;
this.name = name;
this.idOwner = idOwner;
}
// <editor-fold defaultstate="collapsed" desc="Getters">
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "TASK_ID", unique = true, nullable = false)
public int getId() {
return id;
}
#Column(name = "TASK_NAME")
public String getName() {
return name;
}
#Column(name = "TASK_DESCRIPTION")
public String getDescription() {
return description;
}
#Column(name = "TASK_ID_OWNER")
public int getIdOwner() {
return idOwner;
}
// </editor-fold>
//Setters
}
Can somebody tell/show/explain me what I have to do exactly, to make this work?
Currently your mapping should linking ownerId instead of Task class.
Change your Task class to this
private Person person;
#ManyToOne
#JoinColumn(name = "TASK_ID_OWNER")
public Person getPerson() {
return person;
}
In your Person entity you have declared one-to-many relationship with Task entity like this:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "idOwner")
public List<Task> getLstTasks() {
return lstTasks;
}
Here you have given idOwner to mappedBy attribute, it means you are telling hibernate that there is property in Task class called idOwner which is of type Person.
So you have to modify your Tasks class like this (Changing the variable type from int to Person):
private Person idOwner;
#ManyToOne
#JoinColumn(name = "TASK_ID_OWNER")
public Person getIdOwner() {
return idOwner;
}
public void setIdOwner(Person idOwner) {
this.idOwner=idOwner;
}
If you remove the #JoinColumn annotation then hibernate will create a Join table for your relationship, else it will just create a foreign key in Task table with foreign key column name as TASK_ID_OWNER.

Categories