Lazy loading strange behaviour

泄露秘密 提交于 2019-12-11 11:19:36

问题


I am creating web app with spring-mvc [Layers: Controller -> Service -> DAO -> Entities] and I faced a problem with lazy loading which makes me buffled. In general there is the following relationship. I have an Account [Entity] which can have many Words [Entity] and many Words may be assigned to many Accounts, so this is @ManyToMany.

Account Entity

  @Entity
  @Table(name = "account")
  @Inheritance(strategy = InheritanceType.JOINED)
  public class Account {

  ...

  @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = Word.class)
  @JoinTable(name = "account_word", joinColumns = {@JoinColumn(name="account_id")}, inverseJoinColumns = {@JoinColumn(name="word_id")})
  private List<Word> words;

  public List<Word> getWords() {
      return words;
  }

  public void setWords(List<Word> words) {
      this.words = words;
  }
  }

Word Entity

  @Entity
  @Table(name = "word")
  @Inheritance(strategy = InheritanceType.JOINED)
  public class Word {

  ...

  @Basic
  @NotBlank
  @Column(name = "word")
  private String word;

  @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
  @JoinTable(name = "account_word", joinColumns = {@JoinColumn(name="word_id")}, inverseJoinColumns = {@JoinColumn(name="account_id")})
  private List<Account> accounts;

  public List<Account> getAccounts() {
      return accounts;
  }

  public void setAccounts(List<Account> accounts) {
      this.accounts = accounts;
  }

  ...

  }

The case is that when user logs in I want to show in a view his words. I have:

Controller Class

  @Controller
  @RequestMapping(value="/words")
  public class WordsController {

  @Autowired
  AccountService accountService;

  @Autowired
  WordService wordService;

  @RequestMapping(method=RequestMethod.GET)
  public ModelAndView showWords(Principal principal) {

      ModelAndView model = new ModelAndView("words");
      Word word = new Word();
      List<Word> accountWords = new ArrayList<Word>();

      accountWords.addAll(wordService.listUserWords(principal.getName()));

      model.addObject("word", word);
      model.addObject("accountWords", accountWords);

      return model;
  }

Service Class

  @Transactional
  @Service
  public class WordServiceImpl implements WordService {

  private static final Logger logger = LoggerFactory.getLogger(WordServiceImpl.class);

  @Autowired
  AccountDao accountDao;

  @PersistenceContext
  EntityManager entityManager;

  @Override
  @Transactional(propagation = Propagation.REQUIRED)
  public Collection<Word> listUserWords(String username) {
      try {
          Account foundAccount = accountDao.findUser(username);
          List<Word> userWords = foundAccount.getWords();
          for (Word word : userWords) {
              logger.info("Word: " + word.getWord());
          }
          return userWords;
      } catch (UserNotFoundException unf) {
          logger.error("User not found: " + username);
      }
      return null;
  }
  }

DAO Class

  @Repository
  public class AccountDaoImpl implements AccountDao {

  @PersistenceContext
  private EntityManager entityManager;
  private CriteriaBuilder cb;

  @PostConstruct
  private void init() {
      cb = entityManager.getCriteriaBuilder();
  }

  @Override
  public Account findUser(String username) throws UserNotFoundException {
      CriteriaQuery<Account> c = cb.createQuery(Account.class);
      Root<Account> r = c.from(Account.class);
      try {
          c.select(r).where(cb.equal(r.get("username"), username));
          Account foundAccount = entityManager.createQuery(c).getSingleResult();
          return foundAccount;
      } catch(NoResultException nre){
          throw new UserNotFoundException();
      }
  }
  }

JSP View

  ...
  <ul id="word_list">
      <c:choose>
          <c:when test="${not empty accountWords}">
               <c:forEach items="${accountWords}" var="word" varStatus="status">
                   <li class="word">
                       <span>${word.word}</span>
                   </li>
               </c:forEach>
          </c:when>
      </c:choose>
  </ul>
  ...

In my Service class I want to use Lazy loading but there is very strange behaviour. The fragment:

   for (Word word : userWords) {
        logger.info("Word: " + word.getWord());
   }

is just for testing but it occured crucial! Without it i'm getting LazyInitializationException and I can't find the reason why this is happening. When I comment this fragment I'm getting:

  [StatefulPersistenceContext] - initializing non-lazy collections
  [Loader] - loading collection: [model.Account.roles#104]
  [AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
  [SQL] - select roles0_.account_id as account2_9_1_, roles0_.role_id as role1_1_, role1_.role_id as role1_10_0_, role1_.name as name10_0_ from account_role roles0_ inner join role role1_ on roles0_.role_id=role1_.role_id where roles0_.account_id=?
  Hibernate: select roles0_.account_id as account2_9_1_, roles0_.role_id as role1_1_, role1_.role_id as role1_10_0_, role1_.name as name10_0_ from account_role roles0_ inner join role role1_ on roles0_.role_id=role1_.role_id where roles0_.account_id=?
  [AbstractBatcher] - about to open ResultSet (open ResultSets: 0, globally: 0)
  [Loader] - result set contains (possibly empty) collection: [model.Account.roles#104]
  [Loader] - result row: EntityKey[model.Role#2]
  [Loader] - found row of collection: [model.Account.roles#104]
  [AbstractBatcher] - about to close ResultSet (open ResultSets: 1, globally: 1)
  [AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
  [TwoPhaseLoad] - resolving associations for [model.Role#2]
  [TwoPhaseLoad] - done materializing entity [model.Role#2]
  [loading.CollectionLoadContext] - 1 collections were found in result set for role: model.Account.roles
  [loading.CollectionLoadContext] - collection fully initialized: [model.Account.roles#104]
  [loading.CollectionLoadContext] - 1 collections initialized for role: model.Account.roles
  [Loader] - done loading collection
  [org.springframework.orm.jpa.JpaTransactionManager] - Initiating transaction commit
  [org.springframework.orm.jpa.JpaTransactionManager] - Committing JPA transaction on EntityManager [ejb.EntityManagerImpl@6f76dd71]
  [transaction.JDBCTransaction] - commit
  [event.def.AbstractFlushingEventListener] - processing flush-time cascades
  [event.def.AbstractFlushingEventListener] - dirty checking collections
  [Collections] - Collection found: [model.Account.roles#104], was: [model.Account.roles#104] (initialized)
  [Collections] - Collection found: [model.Account.words#104], was: [model.Account.words#104] (uninitialized)
  [Collections] - Collection found: [model.Role.accounts#2], was: [model.Role.accounts#2] (uninitialized)
  [event.def.AbstractFlushingEventListener] - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
  [event.def.AbstractFlushingEventListener] - Flushed: 0 (re)creations, 0 updates, 0 removals to 3 collections
  [pretty.Printer] - listing entities:
  [pretty.Printer] - model.Role{accounts=<uninitialized>, name=ROLE_REGISTERED, roleId=2}
  [pretty.Printer] - model.Account{username=mgrodek, registrationDate=2012-01-07 23:15:38.464, accountId=104, words=<uninitialized>, email=mariusz.grodek@gmail.com, roles=[model.Role#2], password=ffd1245c1e1cd7ed0af442ecc9a019e58ff2cbbe4d465b5dc4dc6b8bee16a2bf}
  [transaction.JDBCTransaction] - re-enabling autocommit
  [transaction.JDBCTransaction] - committed JDBC Connection
  [ConnectionManager] - aggressively releasing JDBC connection
  [ConnectionManager] - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
  [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@4ecb36fa [managed: 5, unused: 4, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@791d9ad)
  [org.springframework.orm.jpa.JpaTransactionManager] - Closing JPA EntityManager [ejb.EntityManagerImpl@6f76dd71] after transaction
  [org.springframework.orm.jpa.EntityManagerFactoryUtils] - Closing JPA EntityManager
  [org.springframework.security.web.context.SecurityContextPersistenceFilter] - SecurityContextHolder now cleared, as request processing completed
  [org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter] - Closing JPA EntityManager in OpenEntityManagerInViewFilter
  [org.springframework.orm.jpa.EntityManagerFactoryUtils] - Closing JPA EntityManager
  2012-02-02 29 org.apache.catalina.core.StandardWrapperValve invoke
  SEVERE: Servlet.service() for servlet [sndServlet] in context with path [/snd] threw exception [Request processing failed; nested exception is LazyInitializationException: failed to lazily initialize a collection of role: model.Account.words, no session or session was closed] with root cause
  LazyInitializationException: failed to lazily initialize a collection of role: model.Account.words, no session or session was closed
    at collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    at collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    at collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
    at collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
   ...

But when I have this fragment uncommented the console log is:

  [Loader] - loading collection: [model.Account.words#104]
  [AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
  [SQL] - select words0_.account_id as account1_9_1_, words0_.word_id as word2_1_, word1_.word_id as word1_8_0_, word1_.counter as counter8_0_, word1_.word as word8_0_ from account_word words0_ inner join word word1_ on words0_.word_id=word1_.word_id where words0_.account_id=?
  Hibernate: select words0_.account_id as account1_9_1_, words0_.word_id as word2_1_, word1_.word_id as word1_8_0_, word1_.counter as counter8_0_, word1_.word as word8_0_ from account_word words0_ inner join word word1_ on words0_.word_id=word1_.word_id where words0_.account_id=?
  [AbstractBatcher] - about to open ResultSet (open ResultSets: 0, globally: 0)
  [Loader] - result set contains (possibly empty) collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#5]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#6]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#7]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#8]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#9]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#10]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#11]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#12]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#13]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#14]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#15]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#18]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#19]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#20]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#21]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#22]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#23]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#24]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#25]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#26]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#27]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#28]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#29]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#30]
  [Loader] - found row of collection: [model.Account.words#104]
  [Loader] - result row: EntityKey[model.Word#31]
  [Loader] - found row of collection: [model.Account.words#104]
  [AbstractBatcher] - about to close ResultSet (open ResultSets: 1, globally: 1)
  [AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
  [TwoPhaseLoad] - resolving associations for [model.Word#5]
  [TwoPhaseLoad] - done materializing entity [model.Word#5]
  [TwoPhaseLoad] - resolving associations for [model.Word#6]
  [TwoPhaseLoad] - done materializing entity [model.Word#6]
  [TwoPhaseLoad] - resolving associations for [model.Word#7]
  [TwoPhaseLoad] - done materializing entity [model.Word#7]
  [TwoPhaseLoad] - resolving associations for [model.Word#8]
  [TwoPhaseLoad] - done materializing entity [model.Word#8]
  [TwoPhaseLoad] - resolving associations for [model.Word#9]
  [TwoPhaseLoad] - done materializing entity [model.Word#9]
  [TwoPhaseLoad] - resolving associations for [model.Word#10]
  [TwoPhaseLoad] - done materializing entity [model.Word#10]
  [TwoPhaseLoad] - resolving associations for [model.Word#11]
  [TwoPhaseLoad] - done materializing entity [model.Word#11]
  [TwoPhaseLoad] - resolving associations for [model.Word#12]
  [TwoPhaseLoad] - done materializing entity [model.Word#12]
  [TwoPhaseLoad] - resolving associations for [model.Word#13]
  [TwoPhaseLoad] - done materializing entity [model.Word#13]
  [TwoPhaseLoad] - resolving associations for [model.Word#14]
  [TwoPhaseLoad] - done materializing entity [model.Word#14]
  [TwoPhaseLoad] - resolving associations for [model.Word#15]
  [TwoPhaseLoad] - done materializing entity [model.Word#15]
  [TwoPhaseLoad] - resolving associations for [model.Word#18]
  [TwoPhaseLoad] - done materializing entity [model.Word#18]
  [TwoPhaseLoad] - resolving associations for [model.Word#19]
  [TwoPhaseLoad] - done materializing entity [model.Word#19]
  [TwoPhaseLoad] - resolving associations for [model.Word#20]
  [TwoPhaseLoad] - done materializing entity [model.Word#20]
  [TwoPhaseLoad] - resolving associations for [model.Word#21]
  [TwoPhaseLoad] - done materializing entity [model.Word#21]
  [TwoPhaseLoad] - resolving associations for [model.Word#22]
  [TwoPhaseLoad] - done materializing entity [model.Word#22]
  [TwoPhaseLoad] - resolving associations for [model.Word#23]
  [TwoPhaseLoad] - done materializing entity [model.Word#23]
  [TwoPhaseLoad] - resolving associations for [model.Word#24]
  [TwoPhaseLoad] - done materializing entity [model.Word#24]
  [TwoPhaseLoad] - resolving associations for [model.Word#25]
  [TwoPhaseLoad] - done materializing entity [model.Word#25]
  [TwoPhaseLoad] - resolving associations for [model.Word#26]
  [TwoPhaseLoad] - done materializing entity [model.Word#26]
  [TwoPhaseLoad] - resolving associations for [model.Word#27]
  [TwoPhaseLoad] - done materializing entity [model.Word#27]
  [TwoPhaseLoad] - resolving associations for [model.Word#28]
  [TwoPhaseLoad] - done materializing entity [model.Word#28]
  [TwoPhaseLoad] - resolving associations for [model.Word#29]
  [TwoPhaseLoad] - done materializing entity [model.Word#29]
  [TwoPhaseLoad] - resolving associations for [model.Word#30]
  [TwoPhaseLoad] - done materializing entity [model.Word#30]
  [TwoPhaseLoad] - resolving associations for [model.Word#31]
  [TwoPhaseLoad] - done materializing entity [model.Word#31]
  [loading.CollectionLoadContext] - 1 collections were found in result set for role: model.Account.words
  [loading.CollectionLoadContext] - collection fully initialized: [model.Account.words#104]
  [loading.CollectionLoadContext] - 1 collections initialized for role: model.Account.words
  [StatefulPersistenceContext] - initializing non-lazy collections
  [Loader] - done loading collection
  INFO  [service.WordServiceImpl] - Word: anetka
  INFO  [service.WordServiceImpl] - Word: anetka
  INFO  [service.WordServiceImpl] - Word: anetka
  INFO  [service.WordServiceImpl] - Word: lolo
  INFO  [service.WordServiceImpl] - Word: test
  INFO  [service.WordServiceImpl] - Word: jazda
  INFO  [service.WordServiceImpl] - Word: aloza
  INFO  [service.WordServiceImpl] - Word: tata
  INFO  [service.WordServiceImpl] - Word: jestok
  INFO  [service.WordServiceImpl] - Word: test
  INFO  [service.WordServiceImpl] - Word: tesss
  INFO  [service.WordServiceImpl] - Word: słowo
  INFO  [service.WordServiceImpl] - Word: hmm
  INFO  [service.WordServiceImpl] - Word: hmh
  INFO  [service.WordServiceImpl] - Word: ggd
  INFO  [service.WordServiceImpl] - Word: yyy
  INFO  [service.WordServiceImpl] - Word: yyy
  INFO  [service.WordServiceImpl] - Word: chyba
  INFO  [service.WordServiceImpl] - Word: sdsad
  INFO  [service.WordServiceImpl] - Word: pup
  INFO  [service.WordServiceImpl] - Word: hm
  INFO  [service.WordServiceImpl] - Word: ateraz
  INFO  [service.WordServiceImpl] - Word: gj
  INFO  [service.WordServiceImpl] - Word: test
  INFO  [service.WordServiceImpl] - Word: test
   [org.springframework.orm.jpa.JpaTransactionManager] - Initiating transaction commit
   [org.springframework.orm.jpa.JpaTransactionManager] - Committing JPA transaction on EntityManager [ejb.EntityManagerImpl@1c910477]
   [transaction.JDBCTransaction] - commit
   [event.def.AbstractFlushingEventListener] - processing flush-time cascades
  [event.def.AbstractFlushingEventListener] - dirty checking collections
  [Collections] - Collection found: [model.Account.roles#104], was: [model.Account.roles#104] (initialized)
  [Collections] - Collection found: [model.Account.words#104], was: [model.Account.words#104] (initialized)
  [Collections] - Collection found: [model.Role.accounts#2], was: [model.Role.accounts#2] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#5], was: [model.Word.accounts#5] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#6], was: [model.Word.accounts#6] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#7], was: [model.Word.accounts#7] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#8], was: [model.Word.accounts#8] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#9], was: [model.Word.accounts#9] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#10], was: [model.Word.accounts#10] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#11], was: [model.Word.accounts#11] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#12], was: [model.Word.accounts#12] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#13], was: [model.Word.accounts#13] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#14], was: [model.Word.accounts#14] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#15], was: [model.Word.accounts#15] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#18], was: [model.Word.accounts#18] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#19], was: [model.Word.accounts#19] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#20], was: [model.Word.accounts#20] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#21], was: [model.Word.accounts#21] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#22], was: [model.Word.accounts#22] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#23], was: [model.Word.accounts#23] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#24], was: [model.Word.accounts#24] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#25], was: [model.Word.accounts#25] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#26], was: [model.Word.accounts#26] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#27], was: [model.Word.accounts#27] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#28], was: [model.Word.accounts#28] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#29], was: [model.Word.accounts#29] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#30], was: [model.Word.accounts#30] (uninitialized)
  [Collections] - Collection found: [model.Word.accounts#31], was: [model.Word.accounts#31] (uninitialized)
  [event.def.AbstractFlushingEventListener] - Flushed: 0 insertions, 0 updates, 0 deletions to 27 objects
  [event.def.AbstractFlushingEventListener] - Flushed: 0 (re)creations, 0 updates, 0 removals to 28 collections
  [pretty.Printer] - listing entities:
  [pretty.Printer] - model.Account{username=mgrodek, registrationDate=2012-01-07 23:15:38.464, accountId=104, words=[model.Word#5, model.Word#6, model.Word#7, model.Word#8, model.Word#9, model.Word#10, model.Word#11, model.Word#12, model.Word#13, model.Word#14, model.Word#15, model.Word#18, model.Word#19, model.Word#20, model.Word#21, model.Word#22, model.Word#23, model.Word#24, model.Word#25, model.Word#26, model.Word#27, model.Word#28, model.Word#29, model.Word#30, model.Word#31], email=mariusz.grodek@gmail.com, roles=[model.Role#2], password=ffd1245c1e1cd7ed0af442ecc9a019e58ff2cbbe4d465b5dc4dc6b8bee16a2bf}
  [pretty.Printer] - model.Word{id=31, accounts=<uninitialized>, counter=1, word=test}
  [pretty.Printer] - model.Word{id=30, accounts=<uninitialized>, counter=1, word=test}
  [pretty.Printer] - model.Word{id=27, accounts=<uninitialized>, counter=1, word=hm}
  [pretty.Printer] - model.Word{id=26, accounts=<uninitialized>, counter=1, word=pup}
  [pretty.Printer] - model.Word{id=29, accounts=<uninitialized>, counter=1, word=gj}
  [pretty.Printer] - model.Word{id=28, accounts=<uninitialized>, counter=1, word=ateraz}
  [pretty.Printer] - model.Role{accounts=<uninitialized>, name=ROLE_REGISTERED, roleId=2}
  [pretty.Printer] - model.Word{id=5, accounts=<uninitialized>, counter=1, word=anetka}
  [pretty.Printer] - model.Word{id=9, accounts=<uninitialized>, counter=1, word=test}
  [pretty.Printer] - model.Word{id=8, accounts=<uninitialized>, counter=1, word=lolo}
  [pretty.Printer] - model.Word{id=7, accounts=<uninitialized>, counter=1, word=anetka}
  [pretty.Printer] - model.Word{id=6, accounts=<uninitialized>, counter=1, word=anetka}
  [pretty.Printer] - model.Word{id=20, accounts=<uninitialized>, counter=1, word=hmh}
  [pretty.Printer] - model.Word{id=21, accounts=<uninitialized>, counter=1, word=ggd}
  [pretty.Printer] - model.Word{id=18, accounts=<uninitialized>, counter=1, word=słowo}
  [pretty.Printer] - model.Word{id=19, accounts=<uninitialized>, counter=1, word=hmm}
  [pretty.Printer] - model.Word{id=24, accounts=<uninitialized>, counter=1, word=chyba}
  [pretty.Printer] - model.Word{id=25, accounts=<uninitialized>, counter=1, word=sdsad}
  [pretty.Printer] - model.Word{id=22, accounts=<uninitialized>, counter=1, word=yyy}
  [pretty.Printer] - model.Word{id=23, accounts=<uninitialized>, counter=1, word=yyy}
  [transaction.JDBCTransaction] - re-enabling autocommit
  [transaction.JDBCTransaction] - committed JDBC Connection
  [ConnectionManager] - aggressively releasing JDBC connection
  [ConnectionManager] - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
  [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@3918d722 [managed: 5, unused: 4, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@5bb77832)
  [org.springframework.orm.jpa.JpaTransactionManager] - Closing JPA EntityManager [ejb.EntityManagerImpl@1c910477] after transaction
  [org.springframework.orm.jpa.EntityManagerFactoryUtils] - Closing JPA EntityManager
  [org.springframework.security.web.access.ExceptionTranslationFilter] - Chain processed normally
  [org.springframework.security.web.context.SecurityContextPersistenceFilter] - SecurityContextHolder now cleared, as request processing completed
  [org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter] - Closing JPA EntityManager in OpenEntityManagerInViewFilter
  [org.springframework.orm.jpa.EntityManagerFactoryUtils] - Closing JPA EntityManager

And words are passed to a view and everything is correct. Why this is happening? Could someone help me with it because i don't want to have this fragment with logger in my code anymore.

Maybe there are some problems with fetching and lazy loading is not working properly? I have @Transactional in my Service Class and I use OpenEntityManagerInViewFilter. At the end this is my shorted version of web.xml file:

web.xml

      <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jee="http://www.springframework.org/schema/jee"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

      <filter>
          <filter-name>JpaFilter</filter-name>
          <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>JpaFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

      <display-name>snd</display-name>

      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>     

      <servlet>
          <servlet-name>sndServlet</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      </servlet>

      <servlet-mapping>
          <servlet-name>sndServlet</servlet-name>
          <url-pattern>*.html</url-pattern>
      </servlet-mapping>

  </web-app>

回答1:


Your service class and method is marked @Transactional, when you are executing hibernate operations in a transaction, hibernate session is open, your mapping makes @ManyToMany side as Lazy loaded, when you access property word of lazy loaded object in a loop, session is open and hence hibernate is able to intialize proxy and get them for you and hence they work on view too as they are properly initialized not lazy objects.

When you comment the code, they are lazy proxies and when you try to access them in view, that too a property of that entity i.e. word, it tries to fetch it but its too late no hibernate session is active and hence the exception.

Tweak it to FetchType.EAGER and see the difference.

Hope this helps....




回答2:


Perhaps this is an old issue, but it is something that is putting me in big trouble :).

But my point is, once the entitymanager/persistencecontext is closed, then the reference to the Entity should beheave as a normal POJO class, since it is completely detouched from persistence context. Then being a simple POJO, why it is concerned about lazy-eager loading?



来源:https://stackoverflow.com/questions/9105099/lazy-loading-strange-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!