2012-11-07 175 views
1

我正在尝试编写股票管理系统。但是现在我有几个问题。请帮我解决这些问题。休眠当我试图从数据库中获取数据时,“没有会话或会话已关闭”

我有2个实体。 ItemItemPriceItem一个或多个ItemPrice

当我试图挽救Item对象,它工作正常;但是当我尝试从数据库中检索详细信息时,它会提供以下Exception堆栈跟踪。

 
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) 

这是实体类文件。

<?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> 

单项实体

<?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编码

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是好的,我已经设置了lazy=false,但是它抛出了Exception。 请大家帮帮我。

回答

4

从堆栈跟踪这些行说你Item.itemPrices设置使用延迟初始化:

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

所以,请加为lazy = “false” 表示itemPrices集合:

<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> 
+0

感谢您的帮助 – mtchinthaka

1

hoaz是正确的。当设置延迟加载时,集合在被访问之前不会被加载。我的猜测是,当应用程序尝试访问它时,您已经关闭了与该对象关联的特定会话。

如果您已完全禁用延迟加载,则无法获取堆栈跟踪的延迟加载失败部分。

请发布新的堆栈跟踪。

2

lazy = false不是专业的方式来做到这一点。当你在配置时这意味着你每次访问它都不会使用延迟加载。延迟加载是件好事。并且针对您的问题解决方案只是在该特定的事务方法中调用一个方法“size()”。 只是调用itemprice集合的size()方法。这将初始化收集然后关闭会话。所以你会得到所有的数据。