gpt4 book ai didi

java - 无法懒惰地初始化角色集合,..无法初始化代理 - 无 session - JPA + SPRING

转载 作者:IT老高 更新时间:2023-10-28 13:53:38 26 4
gpt4 key购买 nike

我在 Spring (3.2.2) 中使用 JPA(使用 Hibernate 4.3.3 作为持久性提供程序),我的所有字段都加载正常,但是当我尝试访问我的 Collection 时,它会抛出错误-

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() 但这些都不起作用。在网上搜索时,我发现扩展 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
}
}

最佳答案

问题是当这个方法调用返回时:

Category parentCategory=serviceCategory.findCategoryById(2l);

在这里,您不再处于 @Transactional 上下文中。这意味着链接到 parentCategory 的 session 已关闭。现在,当您尝试访问链接到已关闭 session 的集合时,会发生 No Session 错误。

需要注意的一点是,main 方法在任何 spring bean 之外运行,并且没有持久性上下文的概念。

解决方案是从事务上下文中调用 parentCategory.getAllParentCategoryrefs(),这永远不能成为应用程序的主要方法。

然后将 parentCategory 重新附加到新的持久化上下文,然后调用 getter。

例如,尝试将 parentCategory 传递回同一服务的事务方法:

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());
}

关于java - 无法懒惰地初始化角色集合,..无法初始化代理 - 无 session - JPA + SPRING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22643098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com