问题
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