我正在使用JPA(Hibernate 4 . 3 . 3作为持久性提供者)和Spring (3.2.2),我所有的字段都加载得很好,但是当我试图访问我的集合时,它抛出了错误-
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.br.common.catalog.entity.Category.allParentCategoryXrefs, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:572)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:551)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:140)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:526)
at java.lang.String.valueOf(String.java:2827)
at java.io.PrintStream.println(PrintStream.java:771)
at test.Test.main(Test.java:30)
当我调试这个时,我的实体类中定义的每个集合都有错误-com.sun.jdi.InvocationException发生调用方法。
我尝试使用collection.size()和Hibernate.initialize(),但都不起作用。在Internet上搜索时,我发现扩展Persitence将解决问题。
@PersistenceContext(type=PersistenceContextType.EXTENDED)
protected EntityManager em;
这工作正常,但通过这个我发现em将永远保持开放,现在Spring不会处理这个问题。有没有办法使用Spring解决这个问题。任何帮助都非常感谢。
我的实体是-
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name="CATEGORY")
public class Category implements Serializable {
@Id
@GeneratedValue(generator= "CategoryId")
@Column(name = "CATEGORY_ID")
protected Long id;
@ManyToOne(targetEntity = Category.class)
@JoinColumn(name = "DEFAULT_PARENT_CATEGORY_ID")
@Index(name="CATEGORY_PARENT_INDEX", columnNames={"DEFAULT_PARENT_CATEGORY_ID"})
protected Category defaultParentCategory;
@OneToMany(targetEntity = Categoryref.class, mappedBy = "categoryrefPK.category")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="test")
@OrderBy(value="displayOrder")
@BatchSize(size = 50)
protected List<Categoryref> childCategoryRefs = new ArrayList<Categoryref>(10);
@OneToMany(targetEntity = Categoryref.class, mappedBy = "categoryrefPK.subCategory",fetch=FetchType.LAZY)
@Cascade(value={org.hibernate.annotations.CascadeType.MERGE, org.hibernate.annotations.CascadeType.PERSIST})
@OrderBy(value="displayOrder")
@BatchSize(size = 50)
protected List<Categoryref> parentCategoryRefs = new ArrayList<Categoryref>(10);
}
@Entity
@Polymorphism(type = PolymorphismType.EXPLICIT)
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "CATEGORY_REF")
public class Categoryref implements Serializable {
/** The category id. */
@EmbeddedId
CategoryrefPK categoryrefPK = new CategoryrefPK();
public CategoryrefPK getCategoryrefPK() {
return categoryrefPK;
}
public void setCategoryrefPK(final CategoryrefPK categoryrefPK) {
this.categoryrefPK = categoryrefPK;
}
}
@Embeddable
public class CategoryrefPK implements Serializable {
@ManyToOne(targetEntity = Category.class, optional=false)
@JoinColumn(name = "CATEGORY_ID")
protected Category category = new Category();
@ManyToOne(targetEntity = Category.class, optional=false)
@JoinColumn(name = "SUB_CATEGORY_ID")
protected Category subCategory = new Category();
}
我的Xml配置为-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.br" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
....
</bean>
<!-- this is also used we can used this also -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="abc" />
<property name="packagesToScan" value="com.br.common.*" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
</beans>
Persitence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="abc">
transaction-type="RESOURCE_LOCAL">
<mapping-file>META-INF/category.orm.xml</mapping-file>
<class>com.br.common.Category</class>
<class>com.br.common.Categoryref</class>
<class>com.br.common.CategoryrefPK</class>
<properties>
<property name="javax.persistence.jdbc.user" value="user"
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test>
<property name="javax.persistence.jdbc.password" value="...">
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.transaction.flush_before_completion"
value="false" />
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.generate_statistics" value="false" />
<property name="hibernate.archive.autodetection" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.id.new_generator_mappings" value="true" />
</properties>
</persistence-unit>
</persistence>
这是我的dao,我通过服务层调用dao
@Repository("categoryDaoImpl")
public class CategoryDaoImpl implements ICategoryDAO {
@PersistenceContext
protected EntityManager em;
public Category save(Category category) {
Category category2= em.merge(category);
em.flush();
return category2;
}
public Category readCategoryById(Long categoryId) {
return em.find(Category.class, categoryId);
}
}
服务层
@Service("blCatalogService")
@Transactional(propagation=Propagation.REQUIRED)
public class CatalogServiceImpl implements ICatalogService {
@Resource(name="categoryDaoImpl")
protected ICategoryDAO categoryDao;
@Transactional
public Product saveProduct(Product product) {
return productDao.save(product);
}
public Category findCategoryById(Long categoryId) {
return categoryDao.readCategoryById(categoryId);
}
}
这是主要的
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext-persistence.xml");
ICatalogService serviceCategory= (ICatalogService) context
.getBean("blCatalogService");
Category parentCategory=serviceCategory.findCategoryById(2l);
System.out.println(parentCategory.getAllParentCategoryrefs());//here error is coming while accessing collection
}
}
在您的域集集合上使用@Fetch(FetchMode.SELECT)
和@LazyCollection(LazyCollectionOption.FALSE)
,它会起作用
正如宙斯所说,这个问题已经被回答过很多次了。您的测试类中存在此问题,因为您的事务在服务调用时开始和结束:
Category parentCategory=serviceCategory.findCategoryById(2l);
从 Hibernate 文档中回想一下,延迟加载仅在Hibernate会话中起作用(在本例中,Hibernate会话以服务调用开始和结束)。您无法(仅)重新连接到Hibernate会话来初始化集合。
我不太确定当你想在“Spring”解决它时是什么意思。因为这不是Spring的问题。从本质上讲,解决此问题的两种方法是在加载父级的Hibernate会话中加载集合,或者在原始Hibernate会话之外执行单独的提取。
问题是,当此方法调用返回时:
Category parentCategory=serviceCategory.findCategoryById(2l);
在这里,您不再处于@Transactional
上下文中。这意味着链接到父母类别的会话已关闭。现在,当您尝试访问链接到已关闭会话的集合时,无会话
错误发生。
需要注意的一件事是main方法在任何Spring bean之外运行,并且没有持久性上下文的概念。
解决方案是调用<code>parentCategory。getAllParentCategoryrefs()来自事务上下文,这永远不能成为应用程序的主要方法。
然后将parentCategory重新附加到新的持久性上下文,然后调用getter。
例如,尝试将父母类别传递回同一服务的事务方法:
serviceCategory.nowItWorks(parentCategory);
其中,服务上的方法为事务性:
@Transactional(readOnly=true)
public void nowItWorks(Category category) {
dao.nowItWorks(category);
}
在DAO中:
public void nowItWorks(Category category) {
Category reattached = em.merge(category);
System.out.println("It works: " + reattached.getAllParentCategoryrefs());
}
问题内容: 我使用休眠来创建一个REST API。我创建了一种获取表中所有项目的方法。 这是我的Language.java 这是我的Patient.java 重要提示:Bean和映射是通过NetBeans从MySQL数据库反向工程的。调用时,不需要获取任何与之相关的数据。我的表格只有2列,而。表的前键为 在rest api中使用此方法之前,它没有任何异常即可完美运行。但是,当我在rest api中
问题内容: 我有下一个错误: 我的实体: 我有一个服务班: 我从另一种服务方法调用服务: 但是,当我试图调用这个方法我收到线异常,当我打电话时,也会发生同样的异常上。我已经检查了事务管理器,并且配置正确,并且此步骤中存在事务。另外,我已经检查了关于与此异常相关的stackoverflow的大量答案,但没什么用。 可能是什么原因造成的? 问题答案: 看来模型是一个独立的实体。 尝试合并并在合并实例上
问题内容: 我使用hibernate创建一个REST API。我创建了一种获取表中所有项目的方法。 这是我的Language.java 这是我的Patient.java 重要提示:Bean和映射是通过NetBeans从MySQL数据库反向工程的。调用时,不需要获取任何与之相关的数据。我的表格只有2列,而。表的前键为 在rest api中使用此方法之前,它没有任何异常即可完美运行。但是,当我在res
我正在制作一个网站,我试图在其中订购配料。我选择配料并输入其数量,然后单击添加。我重复了几次。然后我进入下一页,在其中我选择了一个供应商。然后我按“订单”。 预计将Nabavka插入数据库并打开一个页面,说明订单成功,但我收到一个异常,告诉我不能懒惰地初始化它。 来自NabavkaController。java: Nabavka.java: 纳米尔尼卡。java: 纳巴夫卡科帕。java: 纳巴夫
我不明白为什么会发生这种情况。根据代码路径,当引发此异常时,我应该在同一线程中并且会话应存在。 有人能告诉我我错过了什么吗? 我有设置 在hibernate.cfg.xml档案里 我在Servlet过滤器中创建了以下代码 在index.xhtml文件中,我有以下调用: 做一些事情 index.xhtml正在使用使用ui include加载menu.xhtml文件的模板。然后,菜单文件会插入menu
我有一个应用程序,我正在扩展它以提供REST API。在主站点中一切正常,但当我尝试访问REST API时,我在异常日志中得到以下内容: 禁用延迟加载将解决此问题,但会导致不可接受的性能(加载时间从 200 毫秒到 22 秒)。我不知道如何处理这个问题。 我刚开始在ColdFusion中Rest,在我看来,CFC正在以一种不寻常的方式被处理。它们似乎没有被初始化(init方法似乎没有运行),现在看