问题
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