I want to confirm before going my code to production.
I am using LinkedBlockingQueue like shown below.
I have one producer thread and five consumer thread.
Consumer thread does DB operation, So I have increased it to 5 to fasten the process.
Now, is there any way I will run into (Synchronization/Multiple updates for row/or any issue which I need to take care) problem either at Code or DB level.
Below is my complete code.
private int numberOfConsumers = 5;
private LinkedBlockingQueue<RequestParameters> processorQueue;
public void init(){
processorQueue = new LinkedBlockingQueue<RequestParameters>();
for (int i = 0; i < numberOfConsumers ; i++) {
try {
QueueConsumer c = new QueueConsumer(processorQueue);
c.setName("ThreadName-"+i);
c.start();
} catch (Exception e) {
logger.error("", e);
}
}
this.postCallProcessorDaemon = this;
}
class QueueConsumer extends Thread {
private Logger log = Logger.getLogger(QueueConsumer.class);
private final BlockingQueue<RequestParameters> queue;
QueueConsumer(BlockingQueue<RequestParameters> q) { queue = q; }
public void run() {
try {
while (true) {
RequestParameters rp = queue.take();
consumeRecord(rp);
}
} catch (Exception ex) {
log.error("Exception in run method", ex);
}
}
void consumeRecord(RequestParameters requestParameters)
{
try{
process(requestParameters);
} catch (Throwable e) {
log.error("Exception",e);
}
}
private void process(RequestParameters requestParameters) throws Exception{
for (Action each : allActions) {
if(each.doProcessing(requestParameters)){
boolean status = each.process(requestParameters);
}
}
}
}
public boolean process(RequestParameters parameters) {
//In my process method, I am inserting rows in table based on data in Queue.
}
HBM file which I am using for ORM mapping
<class name="CampaignSubscriptionsSummary" table="campaign_subscriptions_summary">
<composite-id name="id" class="com.on.robd.config.db.reports.CampaignSubscriptionsSummaryId">
<key-property name="reportTime" type="timestamp">
<column name="REPORT_TIME" length="19" />
</key-property>
<key-property name="campaignId" type="long">
<column name="CAMPAIGN_ID" />
</key-property>
<key-property name="recipient" type="string">
<column name="RECIPIENT" length="24" />
</key-property>
<key-property name="selectedPack" type="string">
<column name="SELECTED_PACK" length="256" />
</key-property>
</composite-id>
<many-to-one name="campaign" class="com.on.robd.config.db.campaigns.Campaign" update="false" insert="false" fetch="select">
<column name="CAMPAIGN_ID" not-null="true" />
</many-to-one>
<many-to-one name="campaignSubscriptionsStatusDim" class="com.on.robd.config.db.reports.CampaignSubscriptionStatusDim" fetch="select">
<column name="SUBSCRIPTION_STATUS_ID" not-null="true" />
</many-to-one>
<property name="sender" type="string">
<column name="SENDER" length="24" not-null="true" />
</property>
<property name="callDuration" type="java.lang.Integer">
<column name="CALL_DURATION" />
</property>
<property name="dtmfInput" type="string">
<column name="DTMF_INPUT" length="16" not-null="true" />
</property>
<property name="promptForPack" type="string">
<column name="PROMPT_FOR_PACK" length="256" />
</property>
<property name="wavFile" type="string">
<column name="WAV_FILE" length="256" />
</property>
<property name="subscriptionUrl" type="string">
<column name="SUBSCRIPTION_URL" length="256" />
</property>
<property name="language" type="string">
<column name="LANGUAGE" length="256" />
</property>
<property name="reobdTime" type="timestamp">
<column name="REOBD_TIME" length="19" />
</property>
<many-to-one name="campaignTypeDim" class="com.on.robd.config.db.reports.CampaignTypeDim" fetch="select">
<column name="CAMPAIGN_TYPE_ID" not-null="true" />
</many-to-one>
</class>
Most likely you'll have DB locking issues between the consumers, but it depends on your database vendor. Check your DB vendors docs to see if it uses table, row or partition locking on write.
But Regardless you'll get better write performance is you use batch inserting. See http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html . The simplest way to batch, would be to have your Producer push a collection of RequestParameters into your BlockingQueue. This could also reduce the number of open connections you have to the DB which will also help with performance.
Related
I am using Hibernate 4.3.8.
Oracle Release 12.1.0.2.0 .
I have two entity name as Child and Parent Entity.
They are basically joined entity.
We are using Hibernate batching property for performance reason but when it try to save record in Child entity it throws StackOverflowError.
Hibernate Batching property:
<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
Child Entity HBM
<hibernate-mapping>
<class entity-name="ChildEntity_Name" table="ChildEntity_DB" dynamic-insert="true" dynamic-update="true">
<id name="ID" type="java.lang.Long" column="ID">
<generator class="native"/>
</id>
<version name="RevisionId" access="field" column="RevisionId" type="java.lang.Long" unsaved-value="undefined" generated="never"/>
<property name="ModifiedUser" type="java.lang.String" column="ModifiedUser"/>
<property name="DealName_db" type="java.lang.String" column="DealName_db"/>
<property name="TotalPrice_db" type="java.lang.Long" column="TotalPrice_db"/>
<property name="DealDate_db" type="java.lang.String" column="DealDate_db"/>
<property name="ModifiedDate" type="java.util.Date" column="ModifiedDate"/>
<property name="CreatedUser" type="java.lang.String" column="CreatedUser"/>
<property name="CreatedDate" type="java.util.Date" column="CreatedDate"/>
<many-to-one name="CE_UK" entity-name="Parent_Entity_Name" property-ref="UK_PD1" unique="false" fetch="join" update="true" insert="true">
<column name="CustID_db" not-null="true"/>
</many-to-one>
<properties name="UK_Child" unique="true" insert="true" update="true">
<property name="DealId_db" type="java.lang.String" column="DealId_db"/>
</properties>
</class>
</hibernate-mapping>
Parent Entity HBM:
<hibernate-mapping>
<class entity-name="Parent_Entity_Name" table="Parent_Entity_DB" dynamic-insert="true" dynamic-update="true" mutable="true" polymorphism="implicit" select-before-update="false" optimistic-lock="version">
<id name="ID" type="java.lang.Long" column="ID">
<generator class="native"/>
</id>
<version name="RevisionId" access="field" column="RevisionId" type="java.lang.Long" unsaved-value="undefined" generated="never"/>
<property name="ModifiedUser" type="java.lang.String" column="ModifiedUser" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<property name="CustName_db" type="java.lang.String" column="CustName_db" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<property name="CustAddress_db" type="java.lang.String" column="CustAddress_db" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<property name="ModifiedDate" type="java.util.Date" column="ModifiedDate" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<property name="CreatedUser" type="java.lang.String" column="CreatedUser" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<property name="CreatedDate" type="java.util.Date" column="CreatedDate" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
<properties name="UK_PD1" unique="true" insert="true" update="true" optimistic-lock="true">
<property name="CustID_db" type="java.lang.String" column="CustID_db" unique="false" optimistic-lock="true" lazy="false" generated="never"/>
</properties>
</class>
</hibernate-mapping>
Class:
import java.util.HashMap;
import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class TestBatching {
public static void main(String[] args) {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
System.out.println("Got the hibernate session ...");
tx = session.beginTransaction();
System.out.println("Opening tx ...");
Map<String, Object> parentEntityMap = new HashMap();
HashMap uniqueKeyMapping = new java.util.HashMap<>();
uniqueKeyMapping.put("CustID_db", String.valueOf(1));
parentEntityMap.put("CustID_db", String.valueOf(1));
parentEntityMap.put("UK_PD1", uniqueKeyMapping);
parentEntityMap.put("CustName_db", String.valueOf("John"));
parentEntityMap.put("CustAddress_db", String.valueOf("Mumbai"));
parentEntityMap.put("ModifiedDate", java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
parentEntityMap.put("CreatedDate", java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
parentEntityMap.put("ModifiedUser", String.valueOf("User1"));
parentEntityMap.put("CreatedUser", String.valueOf("User1"));
System.out.println("Saving record in Parent Entity ......");
session.save("Parent_Entity_Name", parentEntityMap);
System.out.println("Saved record in Parent Entity ......");
Map<String, Object> childEntityMap = new HashMap();
HashMap uniqueKeyMapping1 = new java.util.HashMap<>();
uniqueKeyMapping1.put("DealId_db", String.valueOf(1));
childEntityMap.put("UK_Child", uniqueKeyMapping1);
childEntityMap.put("DealId_db", String.valueOf(1));
childEntityMap.put("CustID_db", String.valueOf(1));
childEntityMap.put("DealName_db", String.valueOf("SS"));
childEntityMap.put("DealDate_db", "2017-11-15 15:30:14.332");
childEntityMap.put("TotalPrice_db", Long.valueOf(100));
childEntityMap.put("RevisionId", Long.valueOf("1"));
HashMap fkMapping = new java.util.HashMap<>();
fkMapping.put("CustID_db", String.valueOf(1));
fkMapping.put("ID", Long.valueOf("1"));
fkMapping.put("UK_PD1", fkMapping);
fkMapping.put("RevisionId", Long.valueOf("1"));
childEntityMap.put("CE_UK", fkMapping);
childEntityMap.put("ModifiedDate", java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
childEntityMap.put("CreatedDate", java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
childEntityMap.put("ModifiedUser", String.valueOf("User1"));
childEntityMap.put("CreatedUser", String.valueOf("User1"));
System.out.println("Saving record in Child Entity ......");
session.save("ChildEntity_Name", childEntityMap);
System.out.println("Saved record in Child Entity ......");
System.out.println("Flushing session ......");
session.flush();
System.out.println("Flushed session ......");
System.out.println("Commiting tx ......");
tx.commit();
System.out.println("Commited tx ......");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
System.out.println(" closing hibernate session ...");
}
}
}
}
Hibernate Configuration:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#localhost:1521:xe</property>
<property name="hibernate.connection.username">user1</property>
<property name="hibernate.connection.password">user1</property>
<!-- Hibernate caching settings -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<!-- Hibernate-c3p0 settings -->
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.timeout">100</property>
<property name="hibernate.c3p0.max_statements">0</property>
<!-- Hibernate-Batching settings -->
<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<!-- HBM Mapping files -->
<mapping resource="Child_entity.hbm.xml"/>
<mapping resource="Parent_entity.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Output:
Got the hibernate session ...
Opening tx ...
Saving record in Parent Entity ......
Saved record in Parent Entity ......
Saving record in Child Entity ......
Saved record in Child Entity ......
Flushing session ......
closing hibernate session ...
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.lang.Long.hashCode(Long.java:1402)
at java.base/java.util.Objects.hashCode(Objects.java:116)
at java.base/java.util.HashMap$Node.hashCode(HashMap.java:297)
at java.base/java.util.AbstractMap.hashCode(AbstractMap.java:527)
at java.base/java.util.Objects.hashCode(Objects.java:116)
Note: Without hibernate batching property it is working fine.
Can anyone please help me here?
I have two tables user and dailyGame in which there are may-to-mapping. And I want to send following information in response to show daily game list:
gameName
format
startTime
fees
member count (I want to get count from 3rd table ie. dailyGame_user.)
My user.hbm.xml file contains :
<set name="dailyGames" table="dailygame_user"
inverse="false" lazy="true" fetch="select" cascade="all" >
<key>
<column name="userId" not-null="true" />
</key>
<many-to-many entity-name="com.mindbowser.draftDynasty.dto.DailyGameDTO">
<column name="groupId" not-null="true" />
</many-to-many>
</set>
And DailyGame.hbm.xml :
<set name="members" table="dailygame_user" inverse="true" lazy="true" fetch="select">
<key>
<column name="gameId" not-null="true" />
</key>
<many-to-many entity-name="com.mindbowser.draftDynasty.dto.UserDTO">
<column name="userId" not-null="true" />
</many-to-many>
</set>
UserDTO.java:
Set<DailyGameDTO> dailyGames = new HashSet<DailyGameDTO>();
DailyGameDTO.java:
Set<UserDTO> members = new HashSet<UserDTO>();
And for fetching Daily game List I am using following code:
dailyGameDao:
public List<DailyGameDTO> getDailyGameList() {
List<DailyGameDTO> gameList = null;
DailyGameDTO dailyGameDTO=null;
List<DailyGameDTO> memList=null;
try {
Criteria criteria = getCurrentSession().createCriteria(DailyGameDTO.class);
gameList = criteria.list();
} catch (HibernateException ex) {
logger.error(ex.getStackTrace(), ex);
throw ex;
}
return gameList;
}
This "gameList" variable should consist userDTO object but it contains dailyGameDTO object only instead of userDTO .
try to change lazy="true" to lazy="false".
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm working on an application with Spring using SpringMVC, i'm encountering the following error and i don't know how to deal with it .
now i have this message in Console :
org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Integer, got class java.lang.String
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:795)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:788)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at com.sun.proxy.$Proxy11.load(Unknown Source)
at com.my.dao.DepartementImplDB.getDepartementByNom(DepartementImplDB.java:54)
at com.my.dao.DepartementImplDB.addDepartement(DepartementImplDB.java:29)
at com.my.service.DepartementImplMetier.create(DepartementImplMetier.java:57)
at com.my.controller.ImportController.Read(ImportController.java:279)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
this is my ImportController class
/**
* #author Ilias
*/
package com.my.controller;
//import ...
import com.my.dao.Departement;
#Controller
public class ImportController {
DepartementImplMetier dbD = new DepartementImplMetier();
#RequestMapping(value="/read")
public String Read(Model model,#RequestParam CommonsMultipartFile[] fileUpload)
throws IOException, EncryptedDocumentException, InvalidFormatException, java.text.ParseException
{
liste = extraire(modelnom);
for(int m=0, i=29;i<liste.size();i=i+29){//i=i+29
Employe employe= new Employe();
Departement departement = new Departement();
if(i % 29 == 0) m++;
//... Some code here
String dep = (String)liste.get(29*m+13).toString();
Departement d = new Departement();
departement.setNomDepartement(dep);
boolean bool=true;
List<Departement> departements = dbD.getAll();
boolean depbool = true;
for(int j=0;j< departements.size();j++){
if(departements.get(j).getNomDepartement() == dep )
{
depbool = false;
}
if(depbool){
try {
dbD.create(departement);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
for(int n=0;n<employes.size();n++){
if(employes.get(n).getMatriculeMY() == (int)mat )
{
bool= false;
}
}
if(bool){
try {
dbD.create(departement);
dbE.create(employe);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}
return "redirect";
}}
}
this is my Employe.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 5 ao?t 2015 11:05:44 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.my.dao.Employe" table="EMPLOYE">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="nomEmploye" type="java.lang.String">
<column name="NOMEMPLOYE" />
</property>
<property name="prenomEmploye" type="java.lang.String">
<column name="PRENOMEMPLOYE" />
</property>
<property name="matriculeMY" type="int">
<column name="MATRICULEMY" />
</property>
<property name="adresse" type="java.lang.String">
<column name="ADRESSE" />
</property>
<property name="sexe" type="java.lang.String">
<column name="SEXE" />
</property>
<property name="cin" type="java.lang.String">
<column name="CIN" />
</property>
<property name="dateNaissance" type="java.lang.String">
<column name="DATENAISSANCE" />
</property>
<property name="situationFamiliale" type="java.lang.String">
<column name="SITUATIONFAMILIALE" />
</property>
<property name="dateEntree" type="java.lang.String">
<column name="DATEENTREE" />
</property>
<property name="dateSortie" type="java.lang.String">
<column name="DATESORTIE" />
</property>
<property name="numCIMR" type="java.lang.String">
<column name="NUMCIMR" />
</property>
<property name="numCNSS" type="java.lang.String">
<column name="NUMCNSS" />
</property>
<property name="numMUT" type="java.lang.String">
<column name="NUMMUT" />
</property>
<property name="profile" type="java.lang.String">
<column name="PROFILE" />
</property>
<property name="resteConge" type="java.lang.String">
<column name="RESTECONGE" />
</property>
<property name="banque" type="java.lang.String">
<column name="BANQUE" />
</property>
<property name="numCpteBanc" type="java.lang.String">
<column name="NUMCPTEBANC" />
</property>
<!-- <property name="fonction" type="java.lang.String">
<column name="FONCTION" />
</property> -->
<property name="salaire" type="float">
<column name="SALAIRE" />
</property>
<property name="indTransport" type="float">
<column name="INDTRANSPORT" />
</property>
<property name="indRepresent" type="float">
<column name="INDREPRESENT" />
</property>
<property name="indPanier" type="float">
<column name="INDPANIER" />
</property>
<many-to-one name="eDepartement" class="com.my.dao.Departement" access="field" fetch="join">
<column name="EDEPARTEMENT" />
</many-to-one>
<many-to-one name="eFonction" class="com.my.dao.Fonction" access="field" fetch="join">
<column name="EFONCTION" />
</many-to-one>
<many-to-one name="eService" class="com.my.dao.Service" access="field" fetch="join">
<column name="ESERVICE" />
</many-to-one>
<many-to-one name="eTypePaiement" class="com.my.dao.TypePaiement" access="field" fetch="join">
<column name="ETYPEPAIEMENT" />
</many-to-one>
<many-to-one name="eModePaiement" class="com.my.dao.ModePaiement" access="field" fetch="join">
<column name="EMODEPAIEMENT" />
</many-to-one>
</class>
</hibernate-mapping>
this is my Departement.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 5 ao?t 2015 11:05:44 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.my.dao.Departement" table="DEPARTEMENT">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="nomDepartement" type="java.lang.String">
<column name="NOMDEPARTEMENT" />
</property>
<set name="Employe" inverse="true">
<key column="ID" not-null="true"/>
<one-to-many class="com.my.dao.Employe" />
</set>
</class>
</hibernate-mapping>
after debuging, the problem is here :
boolean depbool = true;
for(int j=0;j< departements.size();j++){
if(departements.get(j).getNomDepartement() == dep )
{
depbool = false;
}
if(depbool){
try {
dbD.create(departement);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
exactely here :
dbD.create(departement);
this DepartementImplDB class
package com.my.dao;
import java.util.List;
import org.hibernate.Session;
import com.my.util.HibernateUtil;
/**
* #author Ilias
*
*/
public class DepartementImplDB implements DepartementDao {
/**
* #see com.my.dao.DepartementDao#addDepartement(com.my.dao.Departement)
*/
#Override
public int addDepartement(Departement D) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getInstance().getSessionFactory().getCurrentSession();
session.beginTransaction();System.out.println("********");
session.save(D);System.out.println("departement implement metier");
session.getTransaction().commit();
D=this.getDepartementByNom(D.getNomDepartement());
return D.getId();
}
/**
* #see com.my.dao.DepartementDao#getDepartementById(int)
*/
#Override
public Departement getDepartementById(int id) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getInstance().getSessionFactory().getCurrentSession();
session.beginTransaction();
Departement dept = (Departement) session.load(Departement.class, id);
return dept;
}
/**
* #see com.my.dao.DepartementDao#getDepartementByNom(java.lang.String)
*/
#Override
public Departement getDepartementByNom(String nomDepartement) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getInstance().getSessionFactory().getCurrentSession();
session.beginTransaction();
Departement dept = (Departement) session.load(Departement.class, nomDepartement);
return dept;
}
/**
* #see com.my.dao.DepartementDao#deleteDepartement(int)
*/
#Override
public void deleteDepartement(int id) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getInstance().getSessionFactory().getCurrentSession();
session.beginTransaction();
Departement dept = (Departement) session.load(Departement.class, id);
session.delete(dept);
session.getTransaction().commit();
}
/**
* #see com.my.dao.DepartementDao#updateDepartement(com.my.dao.Departement)
*/
#Override
public void updateDepartement(Departement D) {
// TODO Auto-generated method stub
}
/**
* #see com.my.dao.DepartementDao#getAllDepartement()
*/
#Override
public List<Departement> getAllDepartement() {
// TODO Auto-generated method stub
Session session = HibernateUtil.getInstance().getSessionFactory().getCurrentSession();
session.beginTransaction();
return session.createQuery("from Departement").list();
}
}
this is the link of my last error for more infos : Link
can some one help ?
Your error is
org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Integer, got class java.lang.String
In your stacktrace we can see that dbd.create call others methods
at com.my.dao.DepartementImplDB.getDepartementByNom(DepartementImplDB.java:54)
at com.my.dao.DepartementImplDB.addDepartement(DepartementImplDB.java:29)
In your method
public Departement getDepartementByNom(String nomDepartement)
You try to load a departement with a name but you use session.load wich load by Id.
Departement dept = (Departement) session.load(Departement.class, nomDepartement);
You have to make a Criteria request to load by name. Like
session.beginTransaction();
Criteria criteria = session.createCriteria(Departement.class);
criteria.add(Restrictions.eq("nomDepartement", nomDepartement).ignoreCase());
result = (Departement) criteria.uniqueResult();
session.getTransaction().commit();
ps: In getDepartementById and getDepartementByNom you never end your transaction. Please use pattern like:
try {
session.beginTransaction();
// your code
session.getTransaction().commit();
} catch (HibernateException e) {
LOGGER.error(e);
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
}
Exception:-
Provided id of the wrong type. Expected: class java.lang.Integer, got class java.lang.String
Its very clear by seeing the above line, hibernate is expecting the id as an integer but receiving id in the String format. So it's throwing :-
org.hibernate.TypeMismatchException
I have a query which when i run in sqlDeveloper i get the result. Here is the query
select * from Losa_Cust_Reject_App rejectApp
inner join
Losa_Cust losaCust
on
rejectApp.app_Ref_No = losaCust.app_Ref_No
where
rejectApp.app_Ref_No != '0000001912' and rejectApp.app_Dt >= '23-SEP-2012'
and
rejectApp.cust_Id1 = 'A111111111' and rejectApp.cust_Id1_Type = '01';
i translated this query to hibernate as following
public List findAppByDate(String appRefNo, Date previousAppDate, String currentId1,
String currentIdType1) {
StringBuffer query = new StringBuffer("from ");
query.append(LosaCustRejectApp.class.getName());
query.append(" rejectApp inner join ");
query.append(LosaCust.class.getName());
query.append(" losaCust with rejectApp.appRefNo = losaCust.comp_id.appRefNo");
query.append(" where rejectApp.appRefNo != ? and rejectApp.appDt >= ?");
query.append(" and rejectApp.custId1 = ? and rejectApp.custId1Type = ? ");
List result = null;
try {
result = getHibernateTemplate().find(query.toString(),
new Object[] { appRefNo, previousAppDate, currentId1, currentIdType1 });
if (CollectionUtils.isNotEmpty(result)) {
return result;
}
} catch (Exception e) {
String message = e.getMessage();
System.out.println();
}
return result;
}
But i want to define mapping in hibernate so hibernate make the join automatically. How can i define association in hibernate file for the above query so hibernate make the join automatically.
here is my LosaCustReject.hbm.xml
<hibernate-mapping default-lazy="false">
<class name="com.thetasp.losa.data.LosaCustRejectApp" table="LOSA_CUST_REJECT_APP" optimistic-lock="version">
<id name="rejectAppId" type="java.lang.Long" column="REJECT_APP_ID">
<generator class="com.thetasp.code.runningno.HibernateId">
<param name="fieldCode">REJECT_APP_ID</param>
<param name="returnType">java.lang.Long</param>
</generator>
</id>
<version name="rowVersion" type="int" column="ROW_VERSION" access="property" unsaved-value="undefined" />
<property name="appRefNo" type="java.lang.String" column="APP_REF_NO" not-null="true" length="20" />
<property name="appDt" type="java.sql.Timestamp" column="APP_DT" not-null="true" length="23" />
<property name="custId1Type" type="java.lang.String" column="CUST_ID1_TYPE" not-null="true" length="1" />
<property name="custId1" type="java.lang.String" column="CUST_ID1" not-null="true" length="20" />
.......
<property name="updateDt" type="java.sql.Timestamp" column="UPDATE_DT" length="23" />
<!-- associations -->
</class>
</hibernate-mapping>
LosaCust.hbm.xml
<hibernate-mapping default-lazy="false">
<class name="com.thetasp.losa.data.LosaCust" table="LOSA_CUST" discriminator-value="I" optimistic-lock="version">
<composite-id name="comp_id" class="com.thetasp.losa.data.LosaCustPK">
<key-property name="custId" column="CUST_ID" type="java.lang.String" length="20" />
<key-property name="appRefNo" column="APP_REF_NO" type="java.lang.String" length="20" />
</composite-id>
<discriminator column="CUST_T" type="string" length="1" >
</discriminator>
<version name="rowVersion" type="int" column="ROW_VERSION" access="property" unsaved-value="undefined" />
<property name="custLevel" type="java.lang.String" column="CUST_LEVEL" not-null="false" length="10" />
.....
<property name="staySinceMth" type="java.lang.String" column="STAYED_SINCE_MTH" length="10" />
....
<subclass name="com.thetasp.losa.data.LosaIndvCust" discriminator-value="I" lazy="false" >
<property name="id1Type" type="java.lang.String" column="ID1_TYPE" length="1" />
<property name="id1" type="java.lang.String" column="ID1" length="20" />
....
</subclass>
</class>
Thanks
I think you could do something like this
In LosaCust.java define a field representing the one-to-many association to LosaCustRejectApp entities:
List<LosaCustRejectApp> associatedLosaCustRejectApps;
In LosaCust.hbm.xml you map this new field using something like this:
<list name="associatedLosaCustRejectApps" table="LOSA_CUST_REJECT_APP" >
<key>
<column name="app_Ref_No" not-null="true" />
</key>
<one-to-many class="com.thetasp.losa.data.LosaCustRejectApp" />
</set>
For more details and even a complete tutorial on how to do this type of mapping you can go here:
Hibernate – One-to-Many example (XML Mapping)
Best regards
I am newbie in hybernate and I am struggling with the following exception:
Exception in thread "AWT-EventQueue-0"
org.hibernate.HibernateException: illegally attempted to associate a
proxy with two open Sessions
I get this when I try to delete an object (an order).
My setting/code:
Order.hbm.xml
<hibernate-mapping>
<class name="com.database.entities.Order" table="ORDERS">
<id name="orderId" type="java.lang.Long">
<column name="ORDERID" />
<generator class="identity" />
</id>
<property name="product" type="java.lang.String">
<column name="SHIP" />
</property>
<property name="orderDate" type="java.util.Date">
<column name="ORDERDATE" />
</property>
<property name="quantity" type="java.lang.Integer">
<column name="QUANTITY" />
</property>
<many-to-one name="customer" class="com.database.entities.Customer" fetch="join">
<column name="CUSTOMERID"/>
</many-to-one>
<many-to-one name="associate" column="ASSOCIATEID" class="com.database.entities.Employee" fetch="join">
</many-to-one>
</class>
</hibernate-mapping>
A session holder:
public class DBSession {
private static SessionFactory sessionFactory;
static{
Configuration cfg = new Configuration();
sessionFactory = cfg.configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
}
And relevant DAOs all extending the following:
public abstract class GenericDAO<T, ID extends Serializable> implements GenericDAOIF<T, ID> {
private Class<T> persistentClass;
private Session session;
public Session getSession() {
if(session == null || !session.isOpen()){
session = DBUtil.getSessionFactory().openSession();
}
return session;
}
public void setSession(Session session) {
this.session = session;
}
#SuppressWarnings("unchecked")
#Override
public T findById(ID id, boolean lock) {
T entity;
if(lock)
entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
else
entity = (T) getSession().load(getPersistentClass(), id);
return entity;
}
#Override
public T makePersistent(T entity) {
getSession().beginTransaction();
getSession().saveOrUpdate(entity);
flush();
getSession().getTransaction().commit();
return entity;
}
#Override
public void flush() {
getSession().flush();
}
#Override
public void clear() {
getSession().clear();
}
#Override
public void makeTransient(T entity) {
getSession().getTransaction().begin();
getSession().delete(entity);
getSession().getTransaction().commit();
}
}
While all the other queries work (e.g. insert/select for other entities and order) when I try to delete an order I get the following exception in the following part of the code of GenericDAO:
public void makeTransient(T entity) {
getSession().getTransaction().begin();
getSession().delete(entity);//--> Exception here
getSession().getTransaction().commit();
}
The exception stack trace:
Exception in thread "AWT-EventQueue-0" org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:126)
at org.hibernate.engine.StatefulPersistenceContext.reassociateProxy(StatefulPersistenceContext.java:573)
at org.hibernate.engine.StatefulPersistenceContext.unproxyAndReassociate(StatefulPersistenceContext.java:618)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:956)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:934)
at com.dao.GenericDAO.makeTransient(GenericDAO.java:100)
at com.ui.panels.AdminDBPanel$11.actionPerformed(AdminDBPanel.java:414)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
This happens only when I delete an order (that is why I posted only that part of code).
I do not understand what this exception means.
But searching Google I tried the following which did not work:
1) Merging with session:
#Override
public void makeTransient(T entity) {
getSession().merge(entity);
getSession().getTransaction().begin();
getSession().delete(entity);
getSession().getTransaction().commit();
}
2) Closing the session and reopening it:
public Session getSession() {
if(session == null || !session.isOpen()){
session = DBUtil.getSessionFactory().openSession();
}
else{
session.close();
session = DBUtil.getSessionFactory().openSession();
}
return session;
}
I am stuck on how to debug this.
Any input is highly welcome
UPDATE:
Extra info:
Employee mapping:
<hibernate-mapping>
<class name="com.database.entities.Employee" table="ASSOCIATE">
<id name="assosiateId" type="java.lang.Long">
<column name="ASSOCIATEID" />
<generator class="identity" />
</id>
<property name="firstName" type="java.lang.String" not-null="true">
<column name="FIRSTNAME" />
</property>
<property name="lastName" type="java.lang.String" not-null="true">
<column name="LASTNAME" />
</property>
<property name="userName" type="java.lang.String" not-null="true">
<column name="USERNAME" />
</property>
<property name="password" type="java.lang.String" not-null="true">
<column name="PASSWORD" />
</property>
<set name="orders" table="ORDERS" inverse="true" cascade="all" lazy="true">
<key>
<column name="ASSOCIATEID" />
</key>
<one-to-many class="com.database.entities.Order" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.database.entities.Customer" table="CUSTOMER">
<id name="customerId" type="java.lang.Long">
<column name="CUSTOMERID" />
<generator class="identity" />
</id>
<property name="customerName" type="java.lang.String">
<column name="CUSTOMERNAME" />
</property>
<set name="orders" table="ORDERS" inverse="true" cascade="all" lazy="true">
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many class="com.database.entities.Order" />
</set>
</class>
</hibernate-mapping>
Customer mapping:
<hibernate-mapping>
<class name="com.database.entities.Customer" table="CUSTOMER">
<id name="customerId" type="java.lang.Long">
<column name="CUSTOMERID" />
<generator class="identity" />
</id>
<property name="customerName" type="java.lang.String">
<column name="CUSTOMERNAME" />
</property>
<set name="orders" table="ORDERS" inverse="true" cascade="all" lazy="true">
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many class="com.database.entities.Order" />
</set>
</class>
</hibernate-mapping>
OrderDAO:
public class OrderDAO extends GenericDAO<Order, Long> implements OrderDAOIF {
#Override
public void addOrder(Order order, Customer customer, Associate associate) {
Session session = getSession();
Transaction tx = session.beginTransaction();
order.setAssociate(associate);
order.setCustomer(customer);
session.saveOrUpdate(order);
tx.commit();
session.close();
}
#Override
public void updateOrderStatus(String status, Long orderId) {
Order order = findById(orderId, false);
order.setOrderState(status);
Session session = getSession();
Transaction tx = session.beginTransaction();
session.saveOrUpdate(order);
tx.commit();
session.close();
}
}
The code that starts the exception:
Order order = getFactory().getOrderDAO().findById(Long.valueOf(orderId), false);
getFactory().getOrderDAO().makeTransient(order);//--> Exception thrown here
The error means that you are trying to associate a object loaded in one session with another session. There is a bigger issue with how you are doing session management - but I cannot comment on that without a lot more info. The merge work around you tried can fix the problem with a simple change - use the reference returned by the merge method for further operation.
#Override
public void makeTransient(T entity) {
T newEntityRef = getSession().merge(entity);
getSession().getTransaction().begin();
getSession().delete(newEntityRef);
getSession().getTransaction().commit();
}
The problem is due to this piece of code.
Order order = getFactory().getOrderDAO().findById(Long.valueOf(orderId), false);
getFactory().getOrderDAO().makeTransient(order);//--> Exception thrown here
Assuming that the getOrderDao() is creating a new instance of the the OrderDao class. The call to findById uses a new instance of session (let us call it s1) to load the object. The loaded object is a proxy which is associated with the session that was used to load it. Then next call creates a new OrderDAO (by calling getOrderDAO method) - now when makeTransient is called a new session (let us call this s2) is created. You are now trying to pass a proxy loaded by s1 to s2 - which is what the exception is indicating. Merge method takes the object and either creates a new object in s2 or merges content with an existing object - either ways the input object passed is not changed - the new object that is created will be the return value.
Writing the code this way will also fix the issue without the merge.
OrderDao orderDao = getFactory().getOrderDAO();
Order order = orderDao.findById(Long.valueOf(orderId), false);
orderDao.makeTransient(order);
The other problem with the above code is that the session is not getting closed. Each session uses a JDBC connection - so it will lead to a connection leak.
Take a look at the following to get an idea of how to fix your code. Basically your DAO should not open a new session and should not be managing transactions. You should be doing it outside.
http://community.jboss.org/wiki/SessionsAndTransactions
http://community.jboss.org/wiki/GenericDataAccessObjects