未能懒惰地初始化角色集合,..无法初始化代理 – 没有会话 – JPA + SPRING
我在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 occurred invoking method.
我尝试使用collection.size()和Hibernate.initialize(),但没有一个工作。 在网上搜索我发现延长Persitence将解决问题,即。
@PersistenceContext(type=PersistenceContextType.EXTENDED) protected EntityManager 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 childCategoryRefs = new ArrayList(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 parentCategoryRefs = new ArrayList(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配置如下 –
....
Persitence.xml
transaction-type="RESOURCE_LOCAL"> META-INF/category.orm.xml com.br.common.Category com.br.common.Categoryref com.br.common.CategoryrefPK <property name="javax.persistence.jdbc.user" value="user"
这是我的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的会话已关闭。 现在,当您尝试访问链接到已关闭会话的集合时, No 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()); }
就像@Zeus所说的那样,很多次,很多次都回答过。 您在测试类中遇到此问题,因为您的事务在服务调用时开始和结束:
Category parentCategory=serviceCategory.findCategoryById(2l);
回想一下Hibernate文档,延迟加载仅适用于Hibernate会话(在这种情况下,hibernate会话以服务调用开始和结束)。 您无法重新连接到hibernate会话(简单地)来初始化集合。
当你想“在spring”解决它时,我不确定你的意思。 因为这不是Spring问题。 基本上解决这个问题的两种方法是在加载父进程的hibernate会话中加载集合,或者在原始hibernate会话之外执行单独的fetch。
在域集集合中使用@Fetch(FetchMode.SELECT)
和@LazyCollection(LazyCollectionOption.FALSE)
,它将起作用
尝试使用fetch=FetchType.EAGER
,它会工作
- c3p0在hwaitnate的awaitAvailable中挂起
- 为新项目选择“更好”或更熟悉的技术?
- JPA / Hibernate DDL生成; CHAR与VARCHAR
- 没有合适的司机。 尝试使用Hibernate连接到Heroku上的postgresql数据库
- Hibernate Mapping – 使用关联表连接两个表 – 但是有一个扭曲
- Hibernate和Serializable实体
- java.lang.NoSuchMethodError:javax.persistence.JoinColumn.foreignKey
- 如何在hibernate中使用条件对列表进行排序
- @Transactional的奇怪行为(propagation = Propagation.REQUIRES_NEW)