2014-10-06 2 views
1

Я знаю, что это было задано много раз (уже перехватило большую часть сообщения здесь и на других сайтах), но я не решаюсь решить свою проблему.LazyInitializationException с активной транзакцией и подключением

Моя установка: JPA 2 + 4 + зимуют пружинные 4 + primefaces + JBoss еар 7

Проблемы: Я получил ленивые коллекции в другой боб, но когда я получаю вызвать .size метод() на бобе, он бросает «LazyInitializationException: не удалось лениво инициализировать коллекцию роли: com.pe.controlLines.data.model.Activity.activityRisks, не удалось инициализировать прокси - нет сеанса»

Я уверен, что у меня есть активная транзакция, следующая за этим LazyInitializationException Within a @Transactional Method и http://blog.timmattison.com/archives/2012/04/19/tips-for-debugging-springs-transactional-annotation/, поэтому я на 100% уверен, что транзакция работает в то время.

Моя сущность clases:

@Entity 
public class Company { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long companyId; 

    @Column 
    private String name; 

    @OneToOne(cascade={CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) 
    private Activity companieActivities; 

    @OneToMany 
    private Collection<SourceSupervision> sourceSupervisions; 

и вложенный класс

@Entity 
@Indexed 
public class Activity { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long activityId; 

    @ManyToOne 
    @JoinColumn(name="parentActivityId") 
    private Activity parent; 

    @Column 
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
    @Analyzer(definition = "searchtokenanalyzer") 
    private String name; 

    @Column 
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
    @Analyzer(definition = "searchtokenanalyzer") 
    private String description; 

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.REFRESH}) 
    private Collection<ActivityRisk> activityRisks = new ArrayList<ActivityRisk>(); 

    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REFRESH}) 
    private Collection<Word> words; 

    @ManyToMany 
    private Collection<Rol> rolesForActivity; 

делегат Bussines является аннотированными, как это (то Bussines вызывается из контроллера страниц):

@Component 
@Scope("session") 
@Transactional 
public class SystemConfigurationBussinesDelegate { 

Получил inicialization ссылки на объект, который выполняет штраф. (Это из класса aboce)

private Company currentCompany; 

    private Risk currentRisk; 

    @PostConstruct 
    public void init(){ 
     //((WordDAO)wordDAO).startIndexer(); 
     currentCompany = genericDAO.get(Company.class, 1l); 
    } 

Но в этом методе

public List<Danger> getDangers(){ 

     List<Danger> returnValue = new ArrayList<Danger>(); 
     System.out.println(TransactionSynchronizationManager.isActualTransactionActive()); 
     Hibernate.initialize(currentCompany.getCompanieActivities()); 
     currentCompany.getCompanieActivities().getActivityRisks().size(); 
     for(ActivityRisk aRisk : currentCompany.getCompanieActivities().getActivityRisks()){ 
      Risk risk = aRisk.getRisk(); 
      if(risk == currentRisk){ 
       returnValue = new ArrayList<Danger>(aRisk.getDangers()); 
      } 
     } 
     return returnValue; 
    } 

SYSOUT возвращает истину, так что транзакция активна, и я могу видеть открытое подключение к базе данных, в спящем режиме. inicialize работает нормально, а вызов currentCompany.getCompanieActivities(). getActivityRisks(). size(); выдает исключение.

Может ли быть какая-то проблема с контекстами или с чем-то похожими?

Моя конфигурация весной:

<?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:context="http://www.springframework.org/schema/context" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-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-3.0.xsd 
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
         http://www.springframework.org/schema/util 
         http://www.springframework.org/schema/util/spring-util-2.5.xsd 
         http://www.springframework.org/schema/jdbc 
         http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 
         http://www.springframework.org/schema/jee 
         http://www.springframework.org/schema/jee/spring-jee.xsd"> 

    <context:component-scan base-package="com.pe.controlLines" /> 

    <context:annotation-config /> 
    <context:spring-configured /> 

    <aop:aspectj-autoproxy proxy-target-class="true"/> 

    <jee:jndi-lookup id="myDataSource" jndi-name="java:/ControllinesDS"/> 
    <!-- Data Source Declaration --> 
    <!-- Session Factory Declaration <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> --> 
    <!-- Session Factory Declaration --> 
    <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="myDataSource" /> 
     <!-- <property name="packagesToScan"> 
      <list> 
       <value>net.javabeat.spring.model</value> 
      </list> 
     </property> 
     <property name="annotatedClasses"> 
      <list> 
       <value>co.com.testTalos.model.Storage</value> 
       <value>co.com.testTalos.model.Buyer</value> 
       <value>co.com.testTalos.model.Preferences</value> 
      </list> 
     </property>--> 
     <property name="packagesToScan"> 
      <list> 
       <value>com.pe.controlLines.data.model</value> 
      </list> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.search.default.directory_provider">filesystem</prop> 
       <prop key="hibernate.search.default.indexBase">C:/DEVELOPMENT/lucene/indexes</prop> 


      </props> 
     </property> 
    </bean> 

    <!-- Enable the configuration of transactional behavior based on annotations --> 
    <tx:annotation-driven transaction-manager="txManager"/> 

    <!-- Transaction Manager is defined --> 
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="SessionFactory"/> 
    </bean> 

</beans> 

ответ

4

Я думаю, ваша проблема связана с вызовом транзакционный метод внутри @PostConstruct. По дизайну Spring tx аспекты могут быть/неактивны по методу postconstruct, потому что не все бобы гарантированно завершили строительство. Попробуйте найти эту тему, я также помню, что это тоже неожиданно, но есть много полезных статей.

С тех пор мои предпочтительные альтернативы, когда мне нужно tx на постконструменте, - это использовать программную транзакцию (см. Шаблоны Spring TransactionTemplate) использовать ContextRefreshedEvent. См. Ниже пример:

+0

U не может даже представить себе, насколько вы счастливы, что вы только что сделали меня ... спасибо, с вашим ответом и некоторым тестом JUnit, я должен решить все свои проблемы. –

Смежные вопросы