I am using Hibernate dynamic modeling for persisting my objects. The issue i am facing right now is it is throwing exception when i am calling saveOrUpdate function. The exception is
2020-07-08 23:14:06 WARN SqlExceptionHelper:137 - SQL Error: 1062, SQLState: 23000
2020-07-08 23:14:06 ERROR SqlExceptionHelper:142 - Duplicate entry 'TYUTQ-2020-07-08 20:19:53' for key 'PRIMARY'
2020-07-08 23:14:06 ERROR ExceptionMapperStandardImpl:39 - HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
When object is going to insert first time, it will successfully inserted but when object is already present in the database then saveOrUpdate method again call the insert method. I verified by using SHOW_SQL = "true" property.
The question is why it is not calling the update method?
Hibernate mapping file is :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class entity-name="myTable">
<composite-id>
<key-property name="code" column="code" type="java.lang.String" />
<key-property name="datetime" column="datetime" type="java.sql.Timestamp" />
</composite-id>
<property name="A" column="A_colummn" type="java.math.BigDecimal" />
<property name="B" column="B_column" type="java.math.BigDecimal" />
<property name="C" column="C_column" type="java.math.BigDecimal" />
<property name="D" column="D_column" type="java.math.BigDecimal" />
<property name="E" column="E_column" type="java.math.BigDecimal" />
<property name="F" column="F_column" type="int" />
<property name="G" column="G_column" type="java.sql.Timestamp" />
</class>
</hibernate-mapping>
And my code is
List<Map<String, Object>> toBeSaved = getTransformedObjects();// all objects belong to same table
Transaction tx = null;
try (SessionFactory factory = HibernateUtils.getSessionFactoryFromXml(profile, job.getXmlMapping());// Creating Session from XML in my utils class
Session session = factory.openSession()) {
tx = session.beginTransaction();
toBeSaved.forEach(map -> {
session.saveOrUpdate(job.getTableName(), map);
});
tx.commit();// Here exception occurs
} catch (HibernateException e) {
rollbackTransactionAndPrintException(e, destTx);
}
Currently there is only one record in map and content of map is :
{
datetime=2020-07-08 20:19:53.21,
F_column=1,
A_colummn=0.421,
G_column=2020-06-16 17:21:05.0,
code=TYUTQ,
B_column=0.000,
C_column=0.000,
D_column=50.540
}
i am using hibernate version 5.3.5.Final and i am badly stuck in it.
Can anyone tell me how to resolve this ? Thanks in advance.
Related
I am a beginner in Hibernate and I have the below code in one of my projects:
ShortHand o = new ShortHand();
Session sess = noprobs.getSessionFactory().openSession();
sess.getTransaction().setTimeout(noprobs.xActionTimeout);
tx = sess.beginTransaction();
sess.save(o);
For which I get the below error:
ERROR:
org.hibernate.HibernateException: could not determine type of dynamic entity
at org.hibernate.impl.SessionImpl.guessEntityName(SessionImpl.java:1770)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1338)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at cool.wxhy.tms.xyz.ABCD.persistInDb(ABCD.java:235)
at cool.wxhy.tms.xyz.ABCD.subscribeToAmps(ABCD.java:144)
at cool.wxhy.tms.xyz.ABCD.hot(ABCD.java:102)
at cool.wxhy.service.impl.wxhyBase.start(wxhyBase.java:250)
at cool.wxhy.service.api.hello.startAllServices(hello.java:211)
at cool.wxhy.service.impl.heyhi.main(heyhi.java:43)
I am using the HIbernate 3.2.6 jar
I am using the xml config for the HIbernate and not the annotations one. Can someone please help on the issue.
Hibernate Mapping file:
<hibernate-mapping package="bofa.pioneer.tms.objects">
<class name="ShortHand" table="ShortHand">
<id name="key" column="id" unsaved-value="null" type="string" >
<generator class="assigned" />
</id>
<property name="animal" column="animal" type="string"/>
<property name="dog" column="dog" type="string"/>
Entity
public class ShortHand extends LongHand {
//getters and setters are present in the parent LongHand
}
I am new to Hibernate and I am facing a issue. There is a existing Class which is getting loaded using Hibernate. I want to add a Set to that class. And added this block in the Existing parent hbm.xml.
<set name="assocication" table="AssociationLinks" lazy="false" access="field" cascade="lock">
<cache usage="read-only" region="UpstreamLink.AssociationLinks"/>
<key column="COUNTRY_TKEY" foreign-key="COUNTRY_ID" property-ref="countryID"/>
<one-to-many class="com.AssociationLinks" />
</set>
Child Hbm.xml
<class name="AssociationLinks" table="AssociationLinks">
<cache usage="read-only" region="UpstreamLink.AssociationLinks" />
<id name="countryID" type="string" column="COUNTRY_ID" access="field" />
<property name="entityName" column="ENTITY_NAME" type="java.lang.String" access="field" />
</class>
When i add Lazy= true in parent I get the Exception:
016-07-05 03:49:43,680 ERROR org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.MainData.association, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.MainData.association, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
But when i make lazy = false, i am seeing that value in getting in one place, but the place where my Parent class's Parent is accessed, i get the below error.
2016-07-05 07:49:00,005 INFO org.hibernate.event.def.DefaultLoadEventListener - Error performing load command
org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)
at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:794)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:241)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
I am new to hibernate. I have written a simple program with four files in it.
Employee.java it is a bean class with getters n setters in it.
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- property name="hbm2ddl.auto">update</property-->
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.url">dbUrl</property>
<property name="connection.username">uname</property>
<property name="connection.password">pass</property >
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<mapping resource="Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Employee.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernate_prj.Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="empid">
<generator class="native"/>
</id>
<property name="firstName" column="empname" type="string"/>
<property name="dept" column="empdept" type="string"/>
<property name="salary" column="empsal" type="int"/>
</class>
</hibernate-mapping>
StoreData.java
package hibernate_prj;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");
//creating seession factory object
#SuppressWarnings("deprecation")
SessionFactory factory=cfg.buildSessionFactory();
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
try{
Employee e1=new Employee();
e1.setId(115);
e1.setFirstName("sonoo");
e1.setDept("jaiswal");
e1.setSalary(100);
session.persist(e1);//persisting the object
t.commit();//transaction is commited
session.close();
}catch(Exception e)
{
System.out.println("E "+e.toString());
}
System.out.println("successfully saved");
}
}
I have created table using the following sql statement
create table employee (empid number(2,2),empname VARCHAR2(30), empdept varchar2(10), empsal number(5,2));
But when I run this program i get the following error:
org.hibernate.PersistentObjectException: detached entity passed to
persist: hibernate_prj.Employee
Please help me to resolve this
You have set the id of the employee (to 115) but also configured it to get generated. Now Hibernat thinks the entity is already persisted, since it has an id != null, but it is not in the session ... doesn't like that.
Just removing this line
e1.setId(115);
should fix the problem.
The persist function is used for update in this case, here your entity doen't exist on your db so the exception is telling you that you are trying to update an object that doen't have a reference on your db (not linked to an existing row on your db). Try to delete the id assignement and if ot working use session.save(e1); so the ID will be assigned.
I'm trying based on some examples and Hibernate documentation for mapping a Stored Procedure, I just need to insert some data wich is not for a single table, but I got the message:
Could not parse mapping document from resource
The mapping file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Data">
<id column="col_id" name="dataId">
<generator class="assigned" />
</id>
<property column="col_liq" name="dataLiq" />
<property column="col_td" name="dataTd" />
<property column="col_numdcto" name="dataNumDoc" />
<sql-insert callable="true" check="none">
{call sp_update_data(?,?,?,?)}
</sql-insert>
</class>
</hibernate-mapping>
The "Data" object is just a POJO.
I will appreciate any idea or sugestion.
just to let others to know how it works due finally I did it.
The mapping is correct with just one point, Hibernate will set the Id as the last field, so the procedure should get it in that position, at least that you do some "trick".
In Java when calling the procedure is like a normal save, the rest is like working with a normal entity.
I'm working on a program that reads specified columns of an XLS file and saves this data to a MySQL database (InnoDB engine, utf8-default collation).
I implemented a function to check whether the file has changed and if so, the program should only write the differences to the database. I am using Hibernate (with use of the function session.saveOrUpdate()) for mapping and Apache POI for the file handling.
The first time I run this program against an empty database, everything runs pretty well so far.
ISSUE:
I get the MySQLIntegrityConstraintViolationException: Duplicate entry '2014-09-10 16:09:28' for key 'PRIMARY' when there are entries already present in the database (and when I try to feed the program with the exact same XLS file as on the run before, which logically means it should not update or save anything).
To determine whether the data from the database and the data from the XLS file are equal, I use the following code, which fetches all entries from the database into a list of my domain objects (List list) and sorts & compares that to the list of domain objects I get from the XLS file:
public void retrieveFromDB() {
try {
DatabaseManager _dbManager = new DatabaseManager(SessionFactoryUtil.SYSTEM_ID_PARAMETER);
_dbManager.beginTransaction();
setBackupValuesList(_dbManager.getDomainObject());
System.out.println("SIZE OF LIST 1: " + getBackupValuesList().size());
_dbManager.commitTransaction();
_dbManager.endTransaction();
log.info("RETRIEVED DATA FROM DATABASE!");
}
catch (Exception e) {
log.fatal("UNABLE TO OPEN DB CONNECTION OR COMMITING TRANSACTION!");
e.printStackTrace();
}
}
public DomainObject determineLastFromDB(List<DomainObject> backupValuesList) {
DomainObject gdhElement = null;
if (backupValuesList.size() == 0) {
log.info("NO OBJECTS IN DATABASE!");
}
else {
Iterator<DomainObject > itr = backupValuesList.iterator();
gdhElement = itr.next();
while (itr.hasNext()) {
gdhElement = itr.next();
}
}
return gdhElement;
}
public List<DomainObject> removeOldDataFromXLS(DomainObject gdhElement) {
if (backupValuesList.size() == 0 || gdhElement.equals(null)) {
log.info("NO OBJECTS IN DATABASE! COPYING ALL DATA!");
}
else if (backupValuesList.size() != 0 || !(gdhElement.equals(null))) {
Iterator<DomainObject> iter = xlsValuesList.iterator();
while (iter.hasNext()) {
DomainObjectelement = iter.next();
// remove all elements that are older than the latest element
// date in the database
if ((element.getDate().before(gdhElement.getDate()))) {
iter.remove();
}
}
}
return xlsValuesList;
}
My hibernate_localhost.cfg.xml looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/databasename?zeroDateTimeBehavior=convertToNull&autoReconnect=true</property>
<property name="connection.username"> removed </property>
<property name="connection.password"> removed </property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="current_session_context_class">thread</property>
<!-- this will show us all sql statements -->
<property name="hibernate.show_sql">false</property>
<!-- Pooling settings -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="c3p0.min_size">0</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.timeout">600</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">60</property>
<!-- mapping files -->
<mapping resource="path/to/DomainObject.hbm.xml"/>
</session-factory>
</hibernate-configuration>
My Hibernate mapping file looks like this:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 5, 2014 6:01:25 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="path.to.DomainObjectClass" table="tablename">
<id name="date" type="java.sql.Date">
<column name="date" />
<generator class="assigned" />
</id>
<property name="value" type="double">
<column name="value" />
</property>
<property name="whenModified" type="java.lang.String">
<column name="whenModified" />
</property>
</class>
</hibernate-mapping>
What I don't get is the following:
Date (primary key) of latest entry in database: 2014-09-09
Date of latest entry in XLS file: 2014-09-09
Date shown in the Exception as duplicate entry: 2014-09-10 16:09:28
It always shows the current date/time in the Exception (not the date from the XLS entry), which I am definitely NOT trying to save to the database.
I tried a lot of debugging but I don't see the solution while being totally confused! Any hints are highly appreciated!