How to handle Many-To-Many Relation with existed data in Hibernate - java

I had three table i.e,personalinfo,groups_designation,groups_desig_category
personalinfo:pid(personal id)
groups_designation:gid(group id)
groups_desig_category:gid,pid
Actually I have data in both table's (personalinfo,groups_designation).So we have provide one screen.In that,The user selects the group and assign personal id and the data pulled into groups_desig_category table.In this scenario,i mapped like
Personal.hbm.xml:-
<set name="empwthgrp" inverse="true" lazy="true" table="groups_desig_category">
<key>
<column name="pid" not-null="true" />
</key>
<many-to-many entity-name="com.aims.beans.DesignationGroupBean">
<column name="gid" not-null="true" />
</many-to-many>
</set>
Personal.java:-
/**
*
*/
private static final long serialVersionUID = 1L;
private int pid,deptno;
private String name,designation;
private Address address;
private Address permentaddress;
private Set famildtlslst;
private Set empwthgrp=new HashSet();
public Set getEmpwthgrp() {
return empwthgrp;
}
public void setEmpwthgrp(Set empwthgrp) {
this.empwthgrp = empwthgrp;
}
public Set getFamildtlslst() {
return famildtlslst;
}
public void setFamildtlslst(Set famildtlslst) {
this.famildtlslst = famildtlslst;
}
public Address getPermentaddress() {
return permentaddress;
}
public void setPermentaddress(Address permentaddress) {
this.permentaddress = permentaddress;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
GroupingDesig.hbm.xml:-
<class name="beans.DesignationGroupBean" table="groups_designation" proxy=beans.DesignationGroupBean">
<id name="gid" column="gid" type="java.lang.Integer">
<generator class="sequence"><param name="sequence">gid_seq</param> </generator>
</id>
<property name="gname" type="java.lang.String" column="gname" not-null="true" />
<property name="description" type="java.lang.String" column="description" not-null="true" />
<set name="grpwthemp" inverse="true" lazy="true" table="groups_desig_category">
<key>
<column name="gid" not-null="true" />
</key>
<many-to-many entity-name="com.aims.beans.Personal">
<column name="pid" not-null="true" />
</many-to-many>
</set>
</class>
DesignationGroupBean.java:-
private int gid;
private String gname,description;
private Set grpwthemp=new HashSet();
public Set getGrpwthemp() {
return grpwthemp;
}
public void setGrpwthemp(Set grpwthemp) {
this.grpwthemp = grpwthemp;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
Actually I trying session.saveOrUpdate(pBean).But its not working.May be can change one-to many and many-to-one instead of many-to-many relation.I think it is not suitable in this scenario.So,How to handle in this scenario?.If you using reverse engineering then it created as one-to-many and many-to-one relation? why?.Please help me.
Update:-
I am implemented in one-to-many and many-to-one relation hibernate whereas in database its many-to-many relation.then Its working fine and below pasted the hibernate mapping files with one-to-many relation ship
GroupingDesig.hbm.xml:-
<set name="grpwthemp" inverse="true" lazy="true" table="groups_desig_category">
<key>
<column name="gid" not-null="true" />
</key>
<one-to-many class="com.aims.beans.GroupAssignment"/>
<!-- <many-to-many entity-name="com.aims.beans.Personal">
<column name="pid" not-null="true" />
</many-to-many>-->
</set>
Personal.hbm.xml
<set name="empwthgrp" inverse="true" lazy="true" table="groups_desig_category">
<key>
<column name="pid" not-null="true" />
</key>
<one-to-many class="com.aims.beans.GroupAssignment"/>
<!--
<many-to-many entity-name="com.aims.beans.DesignationGroupBean">
<column name="gid" not-null="true" />
</many-to-many>-->
</set>
AssigGroupingDesig.hbm.xml:-
<many-to-one name="personal" column="pid" class="com.aims.beans.Personal" not-null="true"></many-to-one>
<many-to-one name="desigdt" column="gid" class="com.aims.beans.DesignationGroupBean" not-null="true"></many-to-one>
When will be came picture the relation ship?.I have search many-to-many relation example's in web i.e,.
Mykong many-to-many
Please help me.My Question is when will be came/used many-to-many relation ship in real time?.
Update 2:-
Thanks.Removing the inverse tag its working fine.But i have doubt regarding generation of deleting the query.Please check the logs
/* load com.beans.Personal */ select personal0_.pid as pid0_, personal0_.name as name5_0_, personal0_.DEPTNO as DEPTNO5_0_, personal0_.designation as designat4_5_0_, personal0_.pddress1 as pddress5_5_0_, personal0_.pddress2 as pddress6_5_0_, personal0_.pcity as pcity5_0_, personal0_.pstate as pstate5_0_, personal0_1_.HomeAddress1 as HomeAddr2_7_0_, personal0_1_.HomeAddress2 as HomeAddr3_7_0_, personal0_1_.homecity as homecity7_0_, personal0_1_.homestate as homestate7_0_ from personalinfo personal0_, address personal0_1_ where personal0_.pid=personal0_1_.pid and personal0_.pid=?
delete collection com.beans.Personal.empwthgrp */ delete from groups_desig_category where pid=?
insert collection row com.beans.Personal.empwthgrp */ insert into groups_desig_category (pid, gid) values (?, ?)
why generating the "delete from groups_desig_category where pid=?".Plz help me
Update 3:-
Yes.Iam loading the data using session.get.becuase i got exception regarding the some of mandatory fields.that is reason i loaded the data then update the records
per=(Personal)session.get(Personal.class,new Integer(pBean.getPid()));
per.setEmpwthgrp(pBean.getEmpwthgrp());
session.saveOrUpdate(per);

In your many-to-many mappings, you set both of them to inverse. You need to choose one entity that will own the relationship - for that one, in the mapping, you will remove the inverse="true" setting. That will be the entity that, when saved or updated, will persist the person to group relationship.
Since in your question you posted saveOrUpdate(pBean), and I assume pBean is Personal entity, then you need to remove the inverse="true" setting in Personal.hbm.xml.
More info in the reference documentation: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/associations.html#assoc-bidirectional-join-m2m

Related

Repeated column in mapping for entity in hibernate XML mapping

I have been facing an issue of "Repeated column in mapping for entity". Could you kindly help me where i have done mistake on it. I have mentioned my code below.
USERAUDIT.hbm.xml
<hibernate-mapping>
<class name="com.mkyong.user.UserAudit" table="USER_AUDIT_TBL">
<id name="eventId" column="EVENT_ID" type="java.lang.Integer">
<generator class="sequence">
<param name="sequence">AUDIT_SEQUENCE</param>
</generator>
</id>
<property name="userId" type="java.lang.Integer">
<column name="USER_ID" length="10" not-null="true" unique="true" />
</property>
<set name="userAuditDtls" table="USER_AUTI_DTLS_TBL" inverse="true"
lazy="true" fetch="select">
<key>
<column name="EVENT_ID" not-null="true" />
</key>
<one-to-many class="com.mkyong.user.UserAuditDtls" />
</set>
</class>
</hibernate-mapping>
USERAUDIT.java
enter code herepublic class UserAudit implements java.io.Serializable {
private Integer eventId;
private Integer userId;
//private UserAuditDtls userAuditDtls;
private Set<UserAuditDtls> userAuditDtls =
new HashSet<UserAuditDtls>(0);
public UserAudit(Integer eventId, Integer userId, Set<UserAuditDtls> userAuditDtls) {
super();
this.eventId = eventId;
this.userId = userId;
this.userAuditDtls = userAuditDtls;
}
public UserAudit() {
super();
// TODO Auto-generated constructor stub
}
public Integer getEventId() {
return eventId;
}
public void setEventId(Integer eventId) {
this.eventId = eventId;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Set<UserAuditDtls> getUserAuditDtls() {
return userAuditDtls;
}
public void setUserAuditDtls(Set<UserAuditDtls> userAuditDtls) {
this.userAuditDtls = userAuditDtls;
}
}
USERAUDITDTLS.hbm.xml
<hibernate-mapping>
<class name="com.mkyong.user.UserAuditDtls" table="PII_USER_AUTI_DTLS_TBL">
<id name="eventId" type="java.lang.Integer">
<column name="EVENT_ID" />
<generator class="foreign">
<param name="property">userAudit</param>
</generator>
</id>
<many-to-one name="userAudit" class="com.mkyong.user.UserAudit" fetch="select">
<column name="EVENT_ID" not-null="true" />
</many-to-one>
<property name="fieldName" type="string">
<column name="FIELD_NAME" length="100" not-null="true" />
</property>
</class>
</hibernate-mapping>
UserAuditDtls.java
public class UserAuditDtls implements java.io.Serializable {
private Integer eventId;
private UserAudit userAudit;
private String fieldName;
public UserAuditDtls() {
super();
// TODO Auto-generated constructor stub
}
public UserAuditDtls(Integer eventId, UserAudit userAudit, String fieldName) {
super();
this.eventId = eventId;
this.userAudit = userAudit;
this.fieldName = fieldName;
}
public Integer getEventId() {
return eventId;
}
public void setEventId(Integer eventId) {
this.eventId = eventId;
}
public UserAudit getUserAudit() {
return userAudit;
}
public void setUserAudit(UserAudit userAudit) {
this.userAudit = userAudit;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}
Main.Java
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
UserAudit audit = new UserAudit();
audit.setUserId(new Integer(100));
session.save(audit);
UserAuditDtls auditDtls = new UserAuditDtls();
auditDtls.setFieldName("Small");
auditDtls.setUserAudit(audit);
audit.getUserAuditDtls().add(auditDtls);
session.save(auditDtls);
session.getTransaction().commit();
Error:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.mkyong.user.UserAuditDtls column: EVENT_ID (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:676)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:698)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:720)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:474)
at org.hibernate.mapping.RootClass.validate(RootClass.java:235)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1335)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1838)
at com.mkyong.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:13)
Tables:
USER_AUDIT_TBL
event_id - pk
userid -integer
USER_AUDIT_DTLS_TBL
event_id- fk
fieldname - varchar
problem is <column name="EVENT_ID" not-null="true" /> in USERAUDITDTLS.hbm.xml

org.hibernate.MappingException: Foreign key () must have same number of columns as the referenced primary key ()

I know this topic is discussed a lot of times here, but I am still stuck on an exception: Foreign key must have same number of columns as the referenced primary key.
I am using Hibernate for mapping via xml file:
public class Product implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer idProduct;
private String titleProduct;
private String reference;
private String description;
private boolean deuxiemeMain;
private double prixUnitaire;
private double prixNegocier;
private boolean valider;
private Integer qteMinOrdred;
private String echantillonGratuit;
private Customer costumer;
private SubCategory subCategory;
private Order order;
private ProductType productType;
private Unity unity;
private byte[] image;
private Collection<Double> prices;
private Collection<Integer> quantities;
private Collection<String> keyWords;
public Product() {
// TODO Auto-generated constructor stub
}
public Integer getIdProduct() {
return idProduct;
}
public String getTitleProduct() {
return titleProduct;
}
public String getReference() {
return reference;
}
public String getDescription() {
return description;
}
public boolean isDeuxiemeMain() {
return deuxiemeMain;
}
public double getPrixUnitaire() {
return prixUnitaire;
}
public double getPrixNegocier() {
return prixNegocier;
}
public boolean isValider() {
return valider;
}
public Integer getQteMinOrdred() {
return qteMinOrdred;
}
public String getEchantillonGratuit() {
return echantillonGratuit;
}
public void setIdProduct(Integer idProduct) {
this.idProduct = idProduct;
}
public void setTitleProduct(String titleProduct) {
this.titleProduct = titleProduct;
}
public void setReference(String reference) {
this.reference = reference;
}
public void setDescription(String description) {
this.description = description;
}
public void setDeuxiemeMain(boolean deuxiemeMain) {
this.deuxiemeMain = deuxiemeMain;
}
public void setPrixUnitaire(double prixUnitaire) {
this.prixUnitaire = prixUnitaire;
}
public void setPrixNegocier(double prixNegocier) {
this.prixNegocier = prixNegocier;
}
public void setValider(boolean valider) {
this.valider = valider;
}
public void setQteMinOrdred(Integer qteMinOrdred) {
this.qteMinOrdred = qteMinOrdred;
}
public void setEchantillonGratuit(String echantillonGratuit) {
this.echantillonGratuit = echantillonGratuit;
}
public Customer getCostumer() {
return costumer;
}
public void setCostumer(Customer costumer) {
this.costumer = costumer;
}
public ProductType getProductType() {
return productType;
}
public void setProductType(ProductType productType) {
this.productType = productType;
}
public Collection<String> getKeyWords() {
return keyWords;
}
public void setKeyWords(Collection<String> keyWords) {
this.keyWords = keyWords;
}
public Unity getUnity() {
return unity;
}
public void setUnity(Unity unity) {
this.unity = unity;
}
public SubCategory getSubCategory() {
return subCategory;
}
public void setSubCategory(SubCategory subCategory) {
this.subCategory = subCategory;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
public Collection<Double> getPrices() {
return prices;
}
public Collection<Integer> getQuantities() {
return quantities;
}
public void setPrices(Collection<Double> prices) {
this.prices = prices;
}
public void setQuantities(Collection<Integer> quantities) {
this.quantities = quantities;
}
}
My Mapping file for Product Class is:
<hibernate-mapping>
<class name="modele.Product" table="PRODUCT">
<id name="idProduct" type="java.lang.Integer">
<column name="IDPRODUCT" />
<generator class="increment" />
</id>
<property name="titleProduct" type="java.lang.String">
<column name="TITLEPRODUCT" />
</property>
<property name="reference" type="java.lang.String">
<column name="REFERENCE" />
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" />
</property>
<property name="deuxiemeMain" type="boolean">
<column name="DEUXIEMEMAIN" />
</property>
<property name="prixUnitaire" type="double">
<column name="PRIXUNITAIRE" />
</property>
<property name="prixNegocier" type="double">
<column name="PRIXNEGOCIER" />
</property>
<property name="valider" type="boolean">
<column name="VALIDER" />
</property>
<property name="qteMinOrdred" type="java.lang.Integer">
<column name="QTEMINORDRED" />
</property>
<property name="echantillonGratuit" type="java.lang.String">
<column name="ECHANTILLONGRATUIT" />
</property>
<many-to-one name="costumer" class="modele.Customer"
fetch="join">
<column name="COSTUMER" />
</many-to-one>
<many-to-one name="subCategory" class="modele.SubCategory"
fetch="join">
<column name="SUBCATEGORY" />
</many-to-one>
<many-to-one name="order" class="modele.Order" fetch="join">
<column name="ORDER" />
</many-to-one>
<many-to-one name="productType" class="modele.ProductType"
fetch="join">
<column name="PRODUCTTYPE" />
</many-to-one>
<many-to-one name="unity" class="modele.Unity" fetch="join">
<column name="UNITY" />
</many-to-one>
<primitive-array name="image" table="PRODUCT">
<key>
<column name="IDPRODUCT" />
</key>
<index></index>
<element type="byte">
<column name="IMAGE" />
</element>
</primitive-array>
<bag name="prices" table="PRODUCT" inverse="false" lazy="true">
<key>
<column name="IDPRODUCT" />
</key>
<element type="java.lang.Double">
<column name="PRICES" />
</element>
</bag>
<bag name="quantities" table="PRODUCT" inverse="false" lazy="true">
<key>
<column name="IDPRODUCT" />
</key>
<element type="java.lang.Integer">
<column name="QUANTITIES" />
</element>
</bag>
<bag name="keyWords" table="PRODUCT" inverse="false" lazy="true">
<key>
<column name="IDPRODUCT" />
</key>
<element type="java.lang.String">
<column name="KEYWORDS" />
</element>
</bag>
</class>
</hibernate-mapping>
I get for this construction the following exception:
org.hibernate.MappingException: Foreign key (FK185958CF30AA9EB1:PRODUCT [IDPRODUCT])) must have same number of columns as the referenced primary key (PRODUCT [IDPRODUCT,idx])
org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:90)
org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:73)
org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1263)
org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1170)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
persistence.BaseDAO.(BaseDAO.java:21)
persistence.BaseDAO.getInstance(BaseDAO.java:42)
dao.SearchDAO.getListeProducts(SearchDAO.java:23)
metier.SearchManager.getProduct(SearchManager.java:13)
presentation.SearchProduct.doGet(SearchProduct.java:40)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Unable to make 'many-to-many' relation between Person and Address class

How do I make many-to-many relation between 2 classes Person and Address ? Following is the POJO for Person and Address respectively.
Person :
public class Person {
private int personID;
private String name;
private Person person;
private List addressList;
public List getAddressList() {
return addressList;
}
public void setAddressList(List addressList) {
this.addressList = addressList;
}
public int getPersonID() {
return personID;
}
public void setPersonID(int personID) {
this.personID = personID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Address :
public class Address {
private int addressID;
private String address;
private Person person;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
The relation I am trying to define is A person can have many addresses and one address can belong to many people.
I am unable to represent this in the mapping xml. This is what I have been able to do till now.
<hibernate-mapping>
<class name="pojo.Person" table="person">
<id name="personID" column="p_id">
<generator class="increment" />
</id>
<property name="name" column="p_name" />
<list name="addressList" table="address">
<key column="a_id" />
<!-- DEFINE MANY TO MANY --!>
</list>
</class>
<class name="pojo.Address" table="address">
<id name="addressID" column="a_id">
<generator class="" />
</id>
<property name="address" />
</class>
</hibernate-mapping>
How do I define many to many relation between these two classes ?
Add private List persons instead of private Person person in Address class.
Configure your mapping.xml like this
//For person.hbm.xml
<list name="addresses" inverse="false" table="person_address">
<key>
<column name="Person_ID" not-null="true" />
</key>
<many-to-many entity-name="domains.Address">
<column name="listAddress_ID" not-null="true" />
</many-to-many>
</list>
//For address.hbm.xml
<list name="persons" inverse="false" table="person_address">
<key>
<column name="listAddress_ID" not-null="true" />
</key>
<many-to-many entity-name="domains.Person">
<column name="Person_ID" not-null="true" />
</many-to-many>
</list>

Hibernate/Spring: Not-null property references a null or transient value

I'm developing an application using Hibernate, Spring and GWT in Java. I used reverse engineering under Hibernate (JBoss Developer Studio used) to obtain POJOs and configuration files from an existing MySQL database. It's very simple database with only two entities: Country and Citizen. They have OneToMany relationship between.
Here is the code:
app entry point:
...
Country country = new Country();
country.setName("NameOfCountry"+i);
country.setPopulation(10000);
Citizen ctz = new Citizen();
ctz.setName("John");
ctz.setSurname("Smith");
ctz.setCountry(country);
country.getCitizens().add(ctz);
service.saveCitizen(ctz, new AsyncCallback<Boolean>(){
#Override
public void onFailure(Throwable caught) {
System.out.println("Problem saving citizen");
}
#Override
public void onSuccess(Boolean result) {
System.out.println("Citizen successfully saved");
}
});
service.saveCountry(country, new AsyncCallback<Boolean>(){
#Override
public void onFailure(Throwable caught) {
System.out.println("Problem saving country");
}
#Override
public void onSuccess(Boolean result) {
System.out.println("Country successfully saved");
}
});
...
-- service provides simple GWT-RPC call to server
Service on server:
#Service("componentService")
public class ComponentServiceImpl implements ComponentService{
#Autowired
private CountryDAO daoCnt;
#Autowired
private CitizenDAO daoCtz;
#Transactional(readOnly=false)
#Override
public boolean saveCitizen(Citizen citizen) {
daoCtz.saveOrUpdate(citizen);
return true;
}
#Transactional(readOnly=false)
#Override
public boolean saveCountry(Country country) {
daoCnt.saveOrUpdate(country);
return true;
}
}
Now SpringDAOs:
CitizenDAO:
#Repository
public class CitizenDAO {
...
public void saveOrUpdate(Citizen citizen){
sessionFactory.getCurrentSession().saveOrUpdate(citizen);
}
...
CountryDAO:
#Repository
public class CountryDAO {
...
public void saveOrUpdate(Country country){
sessionFactory.getCurrentSession().saveOrUpdate(country);
}
...
Finally
Citizen.hbm.xml:
<hibernate-mapping>
<class name="sk.jakub.mod.shared.model.Citizen" table="citizen" catalog="modeldb">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="country" class="sk.jakub.mod.shared.model.Country" fetch="select">
<column name="Country_id" not-null="true" />
</many-to-one>
<property name="name" type="string">
<column name="name" length="45" not-null="true" />
</property>
<property name="surname" type="string">
<column name="surname" length="45" not-null="true" />
</property>
</class>
</hibernate-mapping>
Country.hbm.xml:
<hibernate-mapping>
<class name="sk.jakub.mod.shared.model.Country" table="country" catalog="modeldb">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" length="45" not-null="true" />
</property>
<property name="population" type="int">
<column name="population" not-null="true" />
</property>
<set name="citizens" table="citizen" inverse="true" lazy="true" fetch="select">
<key>
<column name="Country_id" not-null="true" />
</key>
<one-to-many class="sk.jakub.mod.shared.model.Citizen" />
</set>
</class>
</hibernate-mapping>
I havent listed Citizen.java and Country.java because they are only basic POJOs (if necessary I'll provide them).
When I launch my app and I want to save my data into database I obtain following error:
org.hibernate.PropertyValueException: not-null property references a null or transient value: sk.jakub.mod.shared.model.Citizen.country
I can't figure out where is the problem. I was trying also instead of saveOrUpdate method, persist method. Or also to change the order of saving into database. Nothing seemed to work.
Thank you very much for help :) If needed, I can post more code from my application.
EDIT:
code for Citizen.java:
public class Citizen implements java.io.Serializable {
private static final long serialVersionUID = -3102863479088406293L;
private Integer id;
private Country country;
private String name;
private String surname;
public Citizen() {
}
public Citizen(Country country, String name, String surname) {
this.country = country;
this.name = name;
this.surname = surname;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Stat getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return this.surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
Country.java:
public class Country implements java.io.Serializable {
private static final long serialVersionUID = -4085805854508658303L;
private Integer id;
private String name;
private int population;
private Set<Citizen> citizens = new HashSet<Citizen>();
public Country() {
}
public Country(String name, int population) {
this.name = name;
this.population = population;
}
public Country(String name, int population, Set<Citizen> citizens) {
this.name = name;
this.population = population;
this.citizens = citizens;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return this.population;
}
public void setPopulation(int population) {
this.population = population;
}
public Set<Citizen> getCitizens() {
return this.citizens;
}
public void setCitizens(Set<Citizen> citizens) {
this.citizens = citizens;
}
}
Furthermore, I've checked the database manually and Country is saved but citizen is not.
I am seeing that you are creating a Citizen before you create a country. Also both the service calls should be in same transaction for the whole operation to be atomic. The COUNTRY_ID seems to be a self generated id i believe. So once you create the country you can attach that to a citizen but you call stack shows you are creating a citizen which has a Country object which doesnt have an id. This is just my guess. You can try putting both the calls under same transaction and also try creating a Country and attach that country instance to the Citizen.
Please check if you have implemented the equals, hashcode and compareTo (if applicable) methods properly. I have recently faced this problem and resolved it by proper implemetation of these.

Hibernate many-to-many mapping not saved in pivot table

I having problems saving many to many relationships to a pivot table.
The way the pojos are created is unfortunately a pretty long process which spans over a couple of different threads which work on the (to this point un-saved) object until it is finally persisted. I associate the related objects to one another right after they are created and when debugging I can see the List of related object populated with their respective objects. So basically all is fine to this point. When I persist the object everything get saved except the relations in the pivot table.
mapping files:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.thebeansgroup.jwinston.plugin.orm.hibernate.object">
<class name="ShowObject" table="show_object">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set cascade="all" inverse="true" name="venues" table="venue_show">
<key column="show_id"/>
<many-to-many class="VenueObject"/>
</set>
</class>
</hibernate-mapping>
and the other
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.thebeansgroup.jwinston.plugin.orm.hibernate.object">
<class name="VenueObject" table="venue_object">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="latitude" type="integer"/>
<property name="longitude" type="integer"/>
<set cascade="all" inverse="true" name="shows" table="venue_show">
<key column="venue_id"/>
<many-to-many class="ShowObject"/>
</set>
</class>
</hibernate-mapping>
pojos:
public class ShowObject extends OrmObject
{
private Long id;
private String name;
private Set venues;
public ShowObject()
{
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Set getVenues()
{
return venues;
}
public void setVenues(Set venues)
{
this.venues = venues;
}
}
and the other:
public class VenueObject extends OrmObject
{
private Long id;
private String name;
private int latitude;
private int longitude;
private Set shows = new HashSet();
public VenueObject()
{
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public int getLatitude()
{
return latitude;
}
public void setLatitude(int latitude)
{
this.latitude = latitude;
}
public int getLongitude()
{
return longitude;
}
public void setLongitude(int longitude)
{
this.longitude = longitude;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Set getShows()
{
return shows;
}
public void setShows(Set shows)
{
this.shows = shows;
}
}
Might the problem be related to the lack of annotations?
Couple things to try:
You have inverse="true" on both ends of many-to-many. It should be only at one end.
Make your sets not lazy.
You didn't specify column property for many-to-many tag.
So it should look something like this at the end:
<class name="ShowObject" table="show_object">
...
<set lazy="false" cascade="all" name="venues" table="venue_show">
<key column="show_id"/>
<many-to-many class="VenueObject" column="venue_id" />
</set>
</class>
<class name="VenueObject" table="venue_object">
...
<set lazy="false" cascade="all" inverse="true" name="shows" table="venue_show">
<key column="venue_id"/>
<many-to-many class="ShowObject" column="show_id"/>
</set>
</class>

Categories

Resources