As I run my main class (Runner) program I get the following exception :
org.hibernate.id.IdentifierGenerationException: attempted to assign id
from null one-to-one property: country
I don't know the reason, why am I getting this exception.
The mapping xml :
<hibernate-mapping>
<class name="pojo.Country" table="country">
<id name="countryID" column="c_id">
<generator class="increment" />
</id>
<property name="countryName" column="c_name" />
<one-to-one class="pojo.PM" name="pm" cascade="all" />
</class>
<class name="pojo.PM" table="pm">
<id name="countryID" column="c_id">
<generator class="foreign">
<param name="property">country</param>
</generator>
</id>
<property name="pmName" column="pm_name" />
<one-to-one class="pojo.Country" name="country" constrained="true" />
</class>
</hibernate-mapping>
POJO Classes :
Country
public class Country {
private int countryID;
private String countryName;
private PM pm;
public PM getPm() {
return pm;
}
public void setPm(PM pm) {
this.pm = pm;
}
public int getCountryID() {
return countryID;
}
public void setCountryID(int countryID) {
this.countryID = countryID;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
PM
public class PM {
private int countryID;
private String pmName;
private Country country;
public int getCountryID() {
return countryID;
}
public void setCountryID(int countryID) {
this.countryID = countryID;
}
public String getPmName() {
return pmName;
}
public void setPmName(String pmName) {
this.pmName = pmName;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
and this is the class that tries to commit the transaction :
public class Runner {
public static void main(String args[]) {System.out.println("dfdf");
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session session = sessFact.openSession();
Transaction trans = session.beginTransaction();
Country c = new Country();
PM pm = new PM();
pm.setPmName("Manmohan Singh");
c.setCountryName("India");
c.setPm(pm);
session.save(c);
trans.commit();
}
}
SQL that created table :
CREATE TABLE country(c_id INTEGER,c_name TEXT,PRIMARY KEY(c_id));
CREATE TABLE pm(c_id INTEGER,pm_name TEXT);
The problem is the country variable. You should initialize all the attirbutes before trying to do some transactions.
EDIT: In your Hibernate file, you want to generate the PM ID from the ID of the country property. However, this property has never been initialized.
<class name="pojo.PM" table="pm">
<id name="countryID" column="c_id">
<generator class="foreign">
<param name="property">country</param>
</generator>
</id>
<property name="pmName" column="pm_name" />
<one-to-one class="pojo.Country" name="country" constrained="true" />
</class>
So, add pm.setCountry(c); to your code.
Related
I am new to hibernate. My goal is to get query results to an ArrayList but I keep getting the ERROR: HHH000091: Expected type: int, actual value: org.hibernate.collection.internal.PersistentSet
I strongly believe the problem is in my mapping, any help is appreciated.
Errors
ERROR: HHH000123: IllegalArgumentException in class: com.mycompany.mavenproject1.Medicamento, setter method of property: labJoin
Apr 07, 2017 10:23:10 AM org.hibernate.property.BasicPropertyAccessor$BasicSetter set
ERROR: HHH000091: Expected type: int, actual value: org.hibernate.collection.internal.PersistentSet
My HQL query:
from Medicamento as m left join from Laboratorio as l where l.codigoLab=m.codigoLab
Mapping XML:
<class name="com.mycompany.mavenproject1.Medicamento" table="MEDICAMENTO" schema="ADMINFARMACIA" optimistic-lock="version">
<id name="codigoMed" type="long">
<column name="CODIGO_MED" not-null="true"/>
<generator class="assigned" />
</id>
<property name="nombreComercial" type="string">
<column name="NOMBRE_COMERCIAL" length="100" not-null="true" />
</property>
<property name="codigoPrincipio" type="string">
<column name="CODIGO_PRINCIPIO" length="50" not-null="true" />
</property>
<property name="stockMinimo" type="java.lang.Integer">
<column name="STOCK_MINIMO" />
</property>
<property name="codigoLab" type="java.lang.Integer">
<column name="CODIGO_LAB" />
</property>
<property name="comentario" type="string">
<column name="COMENTARIO" length="1000" />
</property>
<property name="existencias" type="java.lang.Integer">
<column name="EXISTENCIAS"/>
</property>
<set name="labJoin" fetch="join">
<key column="CODIGO_LAB" />
<one-to-many class="com.mycompany.mavenproject1.Laboratorio"/>
</set>
</class>
Laboratorio.java:
public class Laboratorio implements java.io.Serializable{
private int codigoLab;
private String nombreLab;
public Laboratorio(){
}
public int getCodigoLab() {
return codigoLab;
}
public void setCodigoLab(int codigoLab) {
this.codigoLab = codigoLab;
}
public String getNombreLab() {
return nombreLab;
}
public void setNombreLab(String nombreLab) {
this.nombreLab = nombreLab;
}
}
Medicamento.java - in this one labJoin and labName are the fields on "Laboratorio" table
public class Medicamento implements java.io.Serializable{
private Long codigoMed;
private String nombreComercial;
private String codigoPrincipio;
private int stockMinimo;
private int codigoLab;
private String comentario;
private int existencias;
private int labJoin;
private String labName;
public Medicamento(){
}
public Long getCodigoMed() {
return codigoMed;
}
public void setCodigoMed(Long codigoMed) {
this.codigoMed = codigoMed;
}
public String getNombreComercial() {
return nombreComercial;
}
public void setNombreComercial(String nombreComercial) {
this.nombreComercial = nombreComercial;
}
public String getCodigoPrincipio() {
return codigoPrincipio;
}
public void setCodigoPrincipio(String codigoPrincipio) {
this.codigoPrincipio = codigoPrincipio;
}
public int getStockMinimo() {
return stockMinimo;
}
public void setStockMinimo(int stockMinimo) {
this.stockMinimo = stockMinimo;
}
public int getCodigoLab() {
return codigoLab;
}
public void setCodigoLab(int codigoLab) {
this.codigoLab = codigoLab;
}
public int getLabJoin() {
return labJoin;
}
public void setLabJoin(int labJoin) {
this.labJoin = labJoin;
}
public String getLabName() {
return labName;
}
public void setLabJoin(String labName) {
this.labName= labName;
}
public String getComentario() {
return comentario;
}
public void setComentario(String comentario) {
this.comentario = comentario;
}
public int getExistencias() {
return existencias;
}
public void setExistencias(int existencias) {
this.existencias = existencias;
}
}
Calling method
private void displayResult(List rl){
ArrayList<Object> oneRow = new ArrayList<Object>();
for (Object o: rl){
Medicamento medList = (Medicamento)o;
System.out.println(labList.getCodigoLab());
oneRow.add(medList.getCodigoMed());
oneRow.add(medList.getExistencias());
oneRow.add(medList.getNombreComercial());
oneRow.add(medList.getLabJoin());
}
LowStockTableModel model = new LowStockTableModel(oneRow);
try{
jTable1.setModel(model);
}
catch (Exception e){
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(),"Error",JOptionPane.ERROR_MESSAGE);
jTextField1.setText("");
}
}
In your mapping, you have this
<set name="labJoin" fetch="join">
<key column="CODIGO_LAB" />
<one-to-many class="com.mycompany.mavenproject1.Laboratorio"/>
</set>
But property labJoin has type int. The type of this property has to be Set<Laboratorio>.
How to resolve this issue org.hibernate.AssertionFailure: null id in com.xxxxxx.Profiles entry (don't flush the Session after an exception occurs)
I'm using hibernate and Mysql, I want to insert the data into a table of my database but I was unable to do it.
Thanks.
This is my Dao:
public class ProfilesDao {
public void addProfile(Profiles profile){
Transaction tx = null;
Session session = HibernateUtil.getSessionFactory().openSession();
try{
tx = session.beginTransaction();
session.save(profile);
session.getTransaction().commit();
} catch (Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
} finally {
session.flush();
session.close();
}
}
}
This is my Bean:
public void addProfile(){
Profiles profiles = new Profiles(getProfileName(),getProfileDescription());
ProfilesDao profilesDao = new ProfilesDao();
profilesDao.addProfile(profiles);
}
This is my POJO:
#Entity
#Table(name="profiles"
,catalog="metaestudiante_project_v1"
, uniqueConstraints = #UniqueConstraint(columnNames="profile_name")
)
public class Profiles implements java.io.Serializable {
private Short profileId;
private String profileName;
private String profileDescription;
private Set userses = new HashSet(0);
public Profiles() {
}
public Profiles(String profileName, String profileDescription) {
this.profileName = profileName;
this.profileDescription = profileDescription;
}
public Profiles(String profileName, String profileDescription, Set userses) {
this.profileName = profileName;
this.profileDescription = profileDescription;
this.userses = userses;
}
#Id #GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="profile_id", unique=true, nullable=false)
public Short getProfileId() {
return this.profileId;
}
public void setProfileId(Short profileId) {
this.profileId = profileId;
}
#Column(name="profile_name", unique=true, nullable=false, length=15)
public String getProfileName() {
return this.profileName;
}
public void setProfileName(String profileName) {
this.profileName = profileName;
}
#Column(name="profile_description", nullable=false, length=140)
public String getProfileDescription() {
return this.profileDescription;
}
public void setProfileDescription(String profileDescription) {
this.profileDescription = profileDescription;
}
#OneToMany(fetch=FetchType.LAZY, mappedBy="profiles")
public Set getUserses() {
return this.userses;
}
public void setUserses(Set userses) {
this.userses = userses;
}
}
And this is my hbm.xml
<hibernate-mapping>
<class name="com.besolapp.model.pojos.Profiles" table="profiles" catalog="metaestudiante_project_v1" optimistic-lock="version">
<id name="profileId" type="java.lang.Byte">
<column name="profile_id" />
<generator class="identity" />
</id>
<property name="profileName" type="string">
<column name="profile_name" length="15" not-null="true" unique="true" />
</property>
<property name="profileDescription" type="string">
<column name="profile_description" length="140" not-null="true" />
</property>
<set name="userses" table="users" inverse="true" lazy="true" fetch="select">
<key>
<column name="profile_id" not-null="true" />
</key>
<one-to-many class="com.besolapp.model.pojos.Users" />
</set>
</class>
</hibernate-mapping>
All this looks like easy but I am getting an error:
org.hibernate.AssertionFailure: null id in com.besolapp.model.pojos.Profiles entry (don't flush the Session after an exception occurs)
Can anybody help me please?
I am new to hibernate. I used MYSQL database. there is date field in my table. its type is DATE. There is a value 1989-08-13. When I get value using hibernate it gives that date as 6189498000000. I want to get value as real date (1989-08-13). Please help me
This is my xml file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Aug 27, 2013 1:03:09 AM by Hibernate Tools 4.0.0 -->
<hibernate-mapping>
<class name="core.classes.Staff" table="staff" catalog="surgercare">
<id name="staffId" type="int">
<column name="staff_ID" />
<generator class="assigned" />
</id>
<property name="staffName" type="string">
<column name="staff_Name" length="150" />
</property>
<property name="staffDesignation" type="string">
<column name="staff_designation" length="50" />
</property>
<property name="createDate" type="timestamp">
<column name="CreateDate" length="19" />
</property>
<property name="createUser" type="string">
<column name="CreateUser" length="200" />
</property>
<property name="lastUpDate" type="timestamp">
<column name="LastUpDate" length="19" />
</property>
<property name="lastUpDateUser" type="string">
<column name="LastUpDateUser" length="200" />
</property>
</class>
</hibernate-mapping>
My class file
import java.util.Date;
public class Staff implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int staffId;
private String staffName;
private String staffDesignation;
private Date createDate;
private String createUser;
private Date lastUpDate;
private String lastUpDateUser;
public Staff() {
}
public Staff(int staffId) {
this.staffId = staffId;
}
public Staff(int staffId, String staffName, String staffDesignation,
Date createDate, String createUser, Date lastUpDate,
String lastUpDateUser) {
this.staffId = staffId;
this.staffName = staffName;
this.staffDesignation = staffDesignation;
this.createDate = createDate;
this.createUser = createUser;
this.lastUpDate = lastUpDate;
this.lastUpDateUser = lastUpDateUser;
}
public int getStaffId() {
return this.staffId;
}
public void setStaffId(int staffId) {
this.staffId = staffId;
}
public String getStaffName() {
return this.staffName;
}
public void setStaffName(String staffName) {
this.staffName = staffName;
}
public String getStaffDesignation() {
return this.staffDesignation;
}
public void setStaffDesignation(String staffDesignation) {
this.staffDesignation = staffDesignation;
}
public Date getCreateDate() {
return this.createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public String getCreateUser() {
return this.createUser;
}
public void setCreateUser(String createUser) {
this.createUser = createUser;
}
public Date getLastUpDate() {
return this.lastUpDate;
}
public void setLastUpDate(Date lastUpDate) {
this.lastUpDate = lastUpDate;
}
public String getLastUpDateUser() {
return this.lastUpDateUser;
}
public void setLastUpDateUser(String lastUpDateUser) {
this.lastUpDateUser = lastUpDateUser;
}
}
this is my controller
tx = ses.beginTransaction();
Query query = ses.createQuery("select s from Staff as s where s.staffId = :ID");
query.setString("ID", docID);
List<Staff> DocDetailsList = castlist(Staff.class,query.list());
tx.commit();
return DocDetailsList;
In your hbm file, there are "timestamp" column type. Let hibernate guess the column type:
<property name="createDate" column="CreateDate" />
In other words, if you have the following property:
java.util.Date createDate;
hibernate3-maven-plugin hibernate3:hbm2ddl goal will create the following column in MySql:
`CreateDate` datetime DEFAULT NULL
Note: datetime and timestamp have different ranges. Same for Java Long (timestamp) and java.util.Date.
I am using hibernate to insert objects of the class meal in a hsql DB It works fine if I only insert 1 object but as soon as I try to insert a second it gives me an error. Here is my code and the error:
public static void main(String[] args) {
Main obj = new Main();
Long mealId1 = obj.saveMeal("Pommes");
Long mealId2 = obj.saveMeal("Doener1");
}
public Long saveMeal(String mealName)
{
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
Long mealId = null;
try {
transaction = session.beginTransaction();
Meal meal = new Meal(mealName);
mealId = (Long) session.save(meal);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
return mealId;
}
package data;
import java.util.List;
import java.util.LinkedList;
public class Meal implements java.io.Serializable {
private long id;
private String name;
private List<Image> images;
private List<Review> reviews;
private Grouping grouping;
public Meal() {
}
public Meal(String mealName) {
name = mealName;
}
public Meal(long mealId, String mealName) {
id = mealId;
name = mealName;
}
public long getId() {
return id;
}
public void setId(long mealId) {
id = mealId;
}
public String getMealName() {
return name;
}
public void setMealName(String mealName) {
name = mealName;
}
public float getAvg() {
float avg = 0;
for (int i = 0; i < reviews.size(); i++)
{
avg = avg + reviews.get(i).getReviewPoints();
}
return avg;
}
public List<Image> getNumberImages(int number) {
assert (number >= 0);
return images.subList(0, number) ;
}
public List<Image> getImages() {
return images;
}
public void setImages(LinkedList<Image> images) {
this.images = images;
}
public List<Review> getReviews(int number) {
assert (number >= 0);
return reviews.subList(0, number) ;
}
public LinkedList<String> getAltNames() {
LinkedList<String> altNames = new LinkedList<String>();
LinkedList<Meal> altNameMeals = grouping.getMeals();
for (int i = 0; i < altNameMeals.size(); i++)
{
altNames.add(altNameMeals.get(i).getMealName());
}
return altNames;
}
public void addReview(Review review) {
if (!reviews.contains(review)) {
reviews.add(review);
}
}
public Grouping getGrouping() {
return grouping;
}
public void setGrouping(Grouping grouping) {
this.grouping = grouping;
}
public void addImage(Image image) {
if (!images.contains(image)) {
images.add(image);
}
}<hibernate-mapping>
<class name="data.Meal" table="MEAL">
<id name="id" type="long" access="field">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String" access="field">
<column name="NAME" />
</property>
<list name="images" inverse="false" table="IMAGE" lazy="true" access="field">
<key>
<column name="ID" />
</key>
<list-index column="column_name" />
<one-to-many class="data.Image" />
</list>
<list name="reviews" inverse="false" table="REVIEW" lazy="true" access="field">
<key>
<column name="ID" />
</key>
<list-index></list-index>
<one-to-many class="data.Review" />
</list>
<many-to-one name="grouping" class="data.Grouping" fetch="join">
<column name="GROUPING" />
</many-to-one>
</class>
First is the main method 2nd the class to be persitet and 3rd the hibernate mapping for the class. This is the error message:
843 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: -104, SQLState: 23505
843 [main] ERROR org.hibernate.util.JDBCExceptionReporter - integrity constraint violation: unique constraint or index violation; SYS_PK_10585 table: MEAL
843 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
You declared that you want to assign values to id property manually (<generator class="assigned" />), but don't actually assign it.
So, you need to assign the value manually or declare different id generation strategy.
This post is an continuation of this post
I have DlUser Class each object of this class may have DLFaceBook class and each object of DlFaceBook can have Friends which are mapped as myFriends.
I'm trying to map relation of the same class as many to many relation using bag mapping,composite primary key and static inner class. my code is the following:
public class DlUser{
public DlUser(){}
Long Id;
String FirstName;
String LastName;
....
DlFaceBook fbuser;
//// all requred
getters and setters...
}
The Facebook user class looks like this as you can see I have the collection of objectes with the class MyFriends:
public class DlFaceBook {
private long dlpId;
private String FbId;
private Collection<MyFriends> Friends;
public DlFaceBook(){}
public void setFbId(String FbId)
{
this.FbId = FbId;
}
public void setFriends(Collection<MyFriends> friends)
{
this.Friends = friends;
}
public Collection<MyFriends> getFriends()
{
return this.Friends;
}
public void setdlpId(long id)
{
this.dlpId = id;
}
public long getdlpId()
{
return this.dlpId;
}
public String getFbId()
{
return this.FbId;
}
}
MyFriends class looks like this:
public class MyFriends {
private MyFriendsId myFriendId;
private DlFaceBook me;
private DlFaceBook myFriend;
public MyFriendsId getmyFriendId(){
return this.myFriendId;
}
public void setmyFriendId(MyFriendsId fid){
this.myFriendId = fid;
}
public void setme(DlFaceBook me){
this.me = me;
}
public void setmyFriend(DlFaceBook friend){
this.myFriend = friend;
}
public DlFaceBook getme(){
return this.me ;
}
public DlFaceBook getmyFriend(){
return this.myFriend ;
}
public MyFriends(DlFaceBook me, DlFaceBook user){
this.me = me ;
this.myFriend = user;
this.myFriendId = new MyFriendsId(me.getdlpId(),user.getdlpId());
}
public static class MyFriendsId implements Serializable {
private long meId;
private long myFrId;
// getter's and setter's
public MyFriendsId() {}
public MyFriendsId(long meId, long myFriendId) {
this.meId = meId;
this.myFrId = myFriendId;
}
// getter's and setter's
public long getmeId(){
return this.meId;
}
public void setmeId(Integer id){
this.meId = id;
}
public long getmyFrId(){
return this.myFrId;
}
public void setmyFrId(long id){
this.myFrId = id;
}
}
}
Now the Mapping:
DlUser.hbm.xml is the following and it's simple:
<hibernate-mapping>
<class name="DlUser" table="Users">
<id name="Id" column="id" >
<generator class="sequence">
<param name="sequence">userseq</param>
</generator>
</id>
<property name="firstName">
<column name="FirstName" />
</property>
<property name="lastName">
<column name="LastName"/>
</property>
<many-to-one
name="FaceBook"
class="DlFaceBook"
cascade="all"
column="dlpId"
unique="true"
/>
</class>
</hibernate-mapping>
DlFacebook.hbm.xml looks like this:
<hibernate-mapping>
<class name="DlFaceBook" table="dlfacebook">
<id name="dlpId" type="java.lang.Long" column="dlpId">
<generator class="increment" />
</id>
<property name="fbId">
<column name="fbId" />
</property>
<bag name="Friends">
<key column="me_Id" />
<one-to-many class="MyFriends"/>
</bag>
</class>
</hibernate-mapping>
Then MyFriends.hbm.xml looks like this:
<hibernate-mapping>
<class name="MyFriends">
<composite-id name="myFriendId" class="MyFriends$MyFriendsId">
<key-property name="meId"/>
<key-property name="myFrId"/>
</composite-id>
<many-to-one name="me" class="DlFaceBook" insert="false" update="false"/>
<many-to-one name="myFriend" class="DlFaceBook" insert="false" update="false"/>
</class>
</hibernate-mapping>
When I'm executing my query I got the following error:
Hibernate: insert into dlfacebook (fbId, dlpId) values (?, ?)
Hibernate: insert into Users (FirstName, LastName, email, twitter, birthday, dlpId, id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: update MyFriends set me_Id=? where meId=? and myFrId=?
Hibernate: update MyFriends set me_Id=? where meId=? and myFrId=?
Oct 2, 2010 1:21:18 PM org.hibernate.jdbc.BatchingBatcher doExecuteBatch
SEVERE: Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at Test.main(Test.java:54)
Oct 2, 2010 1:21:18 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at Test.main(Test.java:54)
Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
I see that this error happens when we trying to update not existing row, but how can I make this code work?
Just Facebook and MyFriends
Facebook Notice add convenience method and MutableLong (later, i tell you why to use MutableLong)
public class Facebook {
private MutableLong id = new MutableLong();
public Long getId() { return id.longValue(); }
public void setId(Long id) { this.id.setValue(id); }
public MutableLong getIdAsMutableLong() {
return id;
}
private Collection<MyFriends> myFriends = new ArrayList<MyFriends>();
public Collection<MyFriends> getMyFriends() { return myFriends; }
public void setMyFriends(Collection<MyFriends> myFriends) { this.myFriends = myFriends; }
/**
* add convenience method
*/
public void addFriend(Facebook myFriendFacebook) {
myFriends.add(new MyFriends(this, myFriendFacebook));
}
}
MyFriends
public class MyFriends {
private MyFriendsId myFriendId;
public MyFriendsId getmyFriendId(){ return this.myFriendId; }
public void setmyFriendId(MyFriendsId myFriendId){ this.myFriendId = myFriendId; }
private Facebook me;
public Facebook getme() { return this.me; }
public void setme(Facebook me){ this.me = me; }
private Facebook myFriend;
public Facebook getmyFriend() { return this.myFriend; }
public void setmyFriend(Facebook friend) { this.myFriend = friend; }
public MyFriends() {}
public MyFriends(Facebook meFacebook, Facebook myFriendFacebook){
this.me = meFacebook ;
this.myFriend = myFriendFacebook;
this.myFriendId = new MyFriendsId(meFacebook.getIdAsMutableLong(), myFriendFacebook.getIdAsMutableLong());
}
public static class MyFriendsId implements Serializable {
private MutableLong meId = new MutableLong();
public Long getMeId() { return this.meId.longValue(); }
public void setMeId(Long id) { this.meId.setValue(id); }
private MutableLong myFriendId = new MutableLong();
public Long getMyFriendId(){ return this.myFriendId.longValue(); }
public void setMyFriendId(Long id) { this.myFriendId.setValue(id); }
public MyFriendsId() {}
public MyFriendsId(MutableLong meId, MutableLong myFriendId) {
this.meId = meId;
this.myFriendId = myFriendId;
}
#Override
public boolean equals(Object o) {
if (!(o instanceof MyFriendsId))
return false;
MyFriendsId other = (MyFriendsId) o;
return new EqualsBuilder()
.append(getMeId(), other.getMeId())
.append(getMyFriendId(), getMyFriendId())
.isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder()
.append(getMeId())
.append(getMyFriendId())
.hashCode();
}
}
}
Mapping
<hibernate-mapping package="br.com._3845772.model.domain">
<class name="User">
<id name="id">
<generator class="native"/>
</id>
<many-to-one cascade="all" class="Facebook" name="facebook"/>
</class>
<class name="Facebook">
<id name="id">
<generator class="native"/>
</id>
<bag cascade="all" name="myFriends">
<key column="ME_FACEBOOK_ID" update="false"/>
<one-to-many class="MyFriends"/>
</bag>
</class>
<class name="MyFriends">
<composite-id class="MyFriends$MyFriendsId" name="myFriendId">
<key-property column="ME_FACEBOOK_ID" name="meId"/>
<key-property column="MY_FRIEND_FACEBOOK_ID" name="myFriendId"/>
</composite-id>
<many-to-one class="Facebook" column="ME_FACEBOOK_ID" insert="false" name="me" update="false"/>
<many-to-one class="Facebook" column="MY_FRIEND_FACEBOOK_ID" insert="false" name="myFriend" update="false"/>
</class>
</hibernate-mapping>
And this sample
Facebook meFacebook = new Facebook();
Facebook myFriendFacebook = new Facebook();
meFacebook.addFriend(myFriendFacebook);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(myFriendFacebook);
session.save(meFacebook);
session.getTransaction().commit();
session.close();
Which gives me
Hibernate: insert into Facebook values ( )
Hibernate: insert into Facebook values ( )
Hibernate: select myfriends_.ME_FACEBOOK_ID, myfriends_.MY_FRIEND_FACEBOOK_ID from MyFriends myfriends_ where myfriends_.ME_FACEBOOK_ID=? and myfriends_.MY_FRIEND_FACEBOOK_ID=?
Hibernate: insert into MyFriends (ME_FACEBOOK_ID, MY_FRIEND_FACEBOOK_ID) values (?, ?)
A couple of notes
Hibernate does not support automatic generation of composite primary key. You must set up its value before saving
Your database must support the target generator strategy (If you does not know which generator strategy your database support, prefer to use a native strategy)
Each entity must supply a no-arg constructor
Now why MutableLong (encapsulated by a Long property) instead of Long ?
Number and its subclasses (Long is a Number) are immutable. So if you want Facebook.id (configured by database) and its counterpart MyFriend$MyFriendId.meId share the same value, you must use MutableLong. When the database set up Facebook.id, MyFriend$MyFriendId.meId automatically get its newest value. But it just occurs if you use a MutableLong.