échoué paresseusement initialiser une collection de rôle,..n'a pas pu initialiser proxy - pas de Session - JPA + RESSORT
Je suis en utilisant JPA(Hibernate 4.3.3 en tant que fournisseur de persistance ) le long de Printemps (3.2.2) , tous mes champs sont de chargement bien, mais lorsque j'essaie d'accéder à ma Collection c'est jeter de l'erreur-
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)
Quand j'ai débogué ce que je recevais d'erreur pour chaque collection défini dans ma classe d'entité - com.sun.jdi.InvocationException occurred invoking method.
J'ai essayé d'utiliser la collection.taille() et Hibernate.initialize (), mais rien de tout cela a fonctionné.
Sur la recherche sur internet, j'ai constaté que l'extension Persitence permettra de résoudre le problème d'ie.
@PersistenceContext(type=PersistenceContextType.EXTENDED)
protected EntityManager em;
cela a bien fonctionné mais au travers de ce que j'ai trouvé que les em restera toujours ouvert , maintenant, le printemps ne sera pas gérer cela. Est-il possible de résoudre ce problème à l'aide de Printemps. Toute Aide est très appréciée.
Mes Entités sont -
@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();
}
Mon Xml de Configuration -
<?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>
c'est mon dao je fais appel dao par le biais de la couche de service
@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);
}
}
servie couche
@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);
}
}
c'est la principale
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
}
}
double possible de hibernate: LazyInitializationException: impossible d'initialiser le proxy
je sais que lorsque cette erreur d'initialisation tardive vient, mais je veux qu'il soit résolu en utilisant le printemps
OriginalL'auteur henrycharles | 2014-03-25
Vous devez vous connecter pour publier un commentaire.
Le problème est que lors de l'appel de cette méthode retourne:
Ici, vous n'êtes plus dans une
@Transactional
contexte. cela signifie que la session lié à parentCategory est fermé. maintenant, lorsque vous essayez d'accéder à une collection liée à une séance à huis clos, leNo Session
erreur se produit.Une chose à remarquer est que la principale méthode s'exécute en dehors de toute spring bean et n'a aucune notion de contexte de persistance.
La solution est d'appeler le
parentCategory.getAllParentCategoryrefs()
à partir d'un contexte transactionnel, qui ne peut jamais être la méthode principale de votre application.Puis rattacher la parentCategory au nouveau contexte de persistance, et puis l'appel de la lecture.
Essayez, par exemple, pour passer le parentCategory retour à une méthode du même service:
où la méthode sur le service transactionnel:
Et dans le DAO:
OriginalL'auteur
Comme @Zeus dit, ce qui a été répondu à plusieurs, BEAUCOUP, à la fois avant. Vous rencontrez ce problème dans votre classe de test parce que votre transaction commence et se termine à votre appel de service:
De rappel de mise en veille prolongée de la documentation que le chargement paresseux ne fonctionne qu'à l'intérieur d'une Session Hibernate (dans ce cas, la session hibernate commence et se termine par un appel de service). Vous ne pouvez pas vous reconnecter à la session hibernate (tout simplement) pour initialiser la collection.
Je ne suis pas exactement sûr de ce que vous voulez dire quand vous voulez résoudre "au printemps." Car ce n'est pas un numéro de Printemps. Essentiellement deux façons de résoudre ce sont à la charge de la collecte à l'intérieur de la session hibernate vous chargez le parent ou d'exécution de séparer les chercher à l'extérieur de l'original de la session hibernate.
Je pense que c'est un cas où la réponse est simple, mais la résolution est complexe. Je ne veux pas banaliser le problème. La réponse dépend vraiment de la façon dont votre code est conçu, et à quel niveau vous êtes en train de tester. Le printemps des résumés beaucoup de code réutilisable pour vous, mais vous devez savoir comment il fonctionne pour l'utiliser efficacement.
OriginalL'auteur
utilisation
@Fetch(FetchMode.SELECT)
et@LazyCollection(LazyCollectionOption.FALSE)
sur votre domaine d'ensemble de la collection , il va travaillerOriginalL'auteur
Essayez d'utiliser
fetch=FetchType.EAGER
, il va travaillerOriginalL'auteur