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.
Related
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.
I am new to Hibernate, As per my knowledge, when hbm2ddl.auto is set to 'update', it should create a table if its doesn't exist, it should create a new column automatically if the new 'property' tag for column is added in mapping file. Right?
But whenever i am trying to run my class, it is throwing "Table or view doesn't exist" instead of creating it. I am using hibernate v5.10
Here's my POC example i am trying to run. Thanks in advance.
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="com.nt.domain.Customer" table="CUSTOMER">
<id name="custNo" length="10" type="int" column="CUSTNO"/>
<property name="customerName" length="20" type="string" column="CUSTNAME"/>
<property name="billAmt" length="10" type="int" column="BILLAMT"/>
</class>
</hibernate-mapping>
Configuration
<?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.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:#localhost:1521:sys</property>
<property name="connection.username">Asif123</property>
<property name="connection.password">Asif123</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/nt/domain/customer.hbm.xml"/>
</session-factory>
Main
package com.nt.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.nt.domain.Customer;
public class UpdateTest {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session ses= factory.openSession();
Transaction tx= ses.beginTransaction();
Customer customer = new Customer();
customer.setCustNo(101);
customer.setCustomerName("Asif");
customer.setBillAmt(1245);
ses.save(customer);
tx.commit();
ses.close();
factory.close();
}
}
Customer
package com.nt.domain;
public class Customer {
int custNo;
String customerName;
int billAmt;
//All getters and setters
}
Exception
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
....
For anyone still searching for an answer, If you want to experience all the functionalities of "update" property like auto table creation, auto adding of columns (both case : if already not available), then go for the 5.0.1.Final version, it is the most stable version supporting them.
I think you need "create", "update" will only update existing tables, see docs:
https://docs.jboss.org/hibernate/orm/5.0/manual/en-US/html/ch03.html
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!
I've been messing around this first hibernate from last few days, after solving going through multiple SO threads
org.hibernate.MappingNotFoundException: resource: *hbm.xml not found
org.hibernate.MappingNotFoundException
org.hibernate.MappingNotFoundException: resource: *hbm.xml not found
i am still unable to figure out how to deal with this
here is my 'hibernate.cfg.xml'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">cijagani</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.1.101/test</property>
<property name="hibernate.connection.username">cijagani</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="/login.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
->Along with this login.hbm.xml
<?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 Jun 28, 2014 6:39:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="login" table="LOGIN">
<id name="username" type="java.lang.String">
<column name="USERNAME" />
<generator class="assigned" />
</id>
<property name="password" type="java.lang.String">
<column name="PASSWORD" />
</property>
</class>
</hibernate-mapping>
->along with log output
INFO: HHH000221: Reading mappings from resource: /login.hbm.xml
Exception in thread "main" org.hibernate.MappingNotFoundException: resource: /login.hbm.xml not found
at org.hibernate.cfg.Configuration.addResource(Configuration.java:738)
at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:2195)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:2167)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2147)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2100)
at org.hibernate.cfg.Configuration.configure(Configuration.java:2015)
at StoreData.main(StoreData.java:14)
->StoreData.java is as below
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
//creating configuration object
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");//populates the data of the configuration file
//creating seession factory object
SessionFactory factory= new AnnotationConfiguration().configure().buildSessionFactory();
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
login e1=new login();
e1.setUsername("vi");
e1.setPassword("8434");
session.persist(e1);//persisting the object
session.getTransaction().commit();//transaction is committed
session.close();
System.out.println("successfully saved");
}
}
any help would be appreciated.
this is the basic steps that need to be followed while developing hibernate application ( am telling you from the basic level)
Steps To Create Hibernate Prog
Create Project
Create package inside the project (This is what I think You have missed (it is mandatory) - Ex: package in.myproject.test)
Create POJO Classes, configuration and hbm files
And at last, write your Java application
Remember
Creating package is must
cfg.configure("hibernate.cfg.xml"); -- we supply configure method, the configuration file name when we give our own name to the configuration file ( Ex - "myConfiguration.cfg.xml" (or) "myConfig.xml" etc).
Even if you supply the default configuration file name i.e "hibernate.cfg.xml", still it is fine (but not recomended)
simply there was error in this
<mapping resource="/login.hbm.xml"></mapping>
i just converted it to this
<mapping resource="login.hbm.xml"></mapping>
and it worked,besides this there were minor errors in field name property of login.hbm.xml which i sorted out by simply changing the names as they were on mysql table name.