Hibernate “No session or session was closed” when i trying to get data from database

旧城冷巷雨未停 提交于 2020-01-05 15:37:08

问题


I am trying to write a stock management system. But now I have a few question. Please help me to sort out these problems.

I have 2 entities. Item and ItemPrice. Item has one or more ItemPrice

When I try to save Item object, it works fine; but when I try to retrieve details from database, it gives following Exception stack trace.

org.hibernate.HibernateException: Found shared references to a collection: com.pos.entities.ItemGroup.items
Hibernate: select itemmodel0_.id as id9_, itemmodel0_.item_model as item2_9_, itemmodel0_.status as status9_ from smartpos.item_model itemmodel0_ where (itemmodel0_.status=? )
Hibernate: select itemsize0_.id as id3_, itemsize0_.item_size as item2_3_, itemsize0_.status as status3_ from smartpos.item_size itemsize0_ where (itemsize0_.status=? )
    at org.hibernate.engine.Collections.processReachableCollection(Collections.java:163)
    at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
    at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
    at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:138)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.pos.dao.ItemDaoImpl.getItem(ItemDaoImpl.java:761)
    at com.pos.manager.ItemManager.getItem(ItemManager.java:296)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:464)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:458)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Nov 7, 2012 12:03:42 PM org.hibernate.LazyInitializationException 
SEVERE: failed to lazily initialize a collection of role: com.pos.entities.Item.itemPrices, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.pos.entities.Item.itemPrices, 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.readSize(AbstractPersistentCollection.java:97)
    at org.hibernate.collection.PersistentSet.size(PersistentSet.java:139)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:520)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:458)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.pos.entities.Item.itemPrices, 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.readSize(AbstractPersistentCollection.java:97)
    at org.hibernate.collection.PersistentSet.size(PersistentSet.java:139)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:520)
    at com.pos.ui.ItemDefinitionForm$RefreshTask.doInBackground(ItemDefinitionForm.java:458)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

This is entity class files.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Nov 3, 2012 10:36:51 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class catalog="smartpos" name="com.pos.entities.ItemPrice" table="item_price" lazy="false">
<id name="id" type="java.lang.Integer">
  <column name="id"/>
  <generator class="identity"/>
</id>
<many-to-one class="com.pos.entities.Item" fetch="select" name="item">
  <column name="item_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.PriceList" fetch="select" name="priceList">
  <column name="price_list_id" not-null="true"/>
</many-to-one>
<property name="price" type="float">
  <column name="price" not-null="true" precision="12" scale="0"/>
</property>

Item Entity

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Nov 3, 2012 10:36:51 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class catalog="smartpos" lazy="false" name="com.pos.entities.Item" table="item">
<id name="id" type="java.lang.Integer">
  <column name="id"/>
  <generator class="identity"/>
</id>
<many-to-one class="com.pos.entities.ItemColor" fetch="select" name="itemColor">
  <column name="item_color_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.ItemModel" fetch="select" name="itemModel">
  <column name="item_model_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.ItemGrade" fetch="select" name="itemGrade">
  <column name="item_grade_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.BusinessPartner" fetch="select" name="businessPartner">
  <column name="supplier_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.ItemSize" fetch="select" name="itemSize">
  <column name="item_size_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.Login" fetch="select" name="login">
  <column name="login_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.ItemGroup" fetch="select" name="itemGroup">
  <column name="item_group_id" not-null="true"/>
</many-to-one>
<many-to-one class="com.pos.entities.ItemBrand" fetch="select" name="itemBrand">
  <column name="item_brand_id" not-null="true"/>
</many-to-one>
<property name="itemCode" type="string">
  <column length="50" name="item_code" not-null="true" unique="true"/>
</property>
<property name="itemName" type="string">
  <column length="200" name="item_name" not-null="true"/>
</property>
<property name="shortName" type="string">
  <column length="100" name="short_name" not-null="true"/>
</property>
<property name="barcode" type="string">
  <column length="50" name="barcode" not-null="true"/>
</property>
<property name="warrentyItem" type="byte">
  <column name="warrenty_item" not-null="true"/>
</property>
<property name="taxableItem" type="byte">
  <column name="taxable_item" not-null="true"/>
</property>
<property name="status" type="byte">
  <column name="status" not-null="true"/>
</property>
<property name="createdDate" type="timestamp">
  <column length="19" name="created_date" not-null="true"/>
</property>
<property name="batchSerial" type="byte">
  <column name="batch_serial" not-null="true"/>
</property>
<property name="warrentyPeriod" type="int">
  <column name="warrenty_period" not-null="true"/>
</property>
<set inverse="true" name="itemPrices" cascade="save-update">
  <key>
    <column name="item_id" not-null="true"/>
  </key>
  <one-to-many class="com.pos.entities.ItemPrice"/>
</set>

GUI Coding

headers = new SupportedMethod().getTableHeaderValues(tblItemPrice);
System.out.println("sdff" + item.getItemPrices().size());
itemPriceSet = item.getItemPrices();
Iterator it = itemPriceSet.iterator();

while (it.hasNext()) {
    ItemPrice ip = (ItemPrice) it.next();
    Vector<Object> oneRow = new Vector<Object>();

    oneRow.add(ip.getId());
    oneRow.add(ip.getPriceList().getPriceListName());
    oneRow.add(Float.toString(ip.getPrice()));

    tableData.add(oneRow);
}
tblItemPrice.setModel(new DefaultTableModel(tableData, headers));

cascade is OK, and I already set lazy=false, but it throws Exception. Please anyone help me.


回答1:


These lines from stacktrace say that your Item.itemPrices set uses lazy initialization:

collection of role: com.pos.entities.Item.itemPrices, no session or session was closed at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
...

So please add lazy="false" to itemPrices collection:

<set inverse="true" name="itemPrices" lazy="false" fetch="select" cascade="save-update">
  <key>
    <column name="item_id" not-null="true"/>
  </key>
  <one-to-many class="com.pos.entities.ItemPrice"/>
</set>



回答2:


lazy=false is not professional way to do this. when you doing it in configuration it means whenever you are accessing it will not use lazy loading. Lazy loading is good thing. and for your problem solution is just call one method "size()" at that particular transaction method. just call itemprice collection's size() method. that will initialize collection then close session. so you will get all data.




回答3:


hoaz is right. When lazy loading is set, the collection is not loaded till it's accessed. And my guess is that when the application tries to access it you have already closed the particular session associated with that object.

If you have completely disabled lazy loading, then you cannot be getting the lazy loading failed part of the stacktrace.

Please post the new stacktrace.



来源:https://stackoverflow.com/questions/13264799/hibernate-no-session-or-session-was-closed-when-i-trying-to-get-data-from-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!