i am a new bee to spring data JPA, so i was trying to make something out of it, so that i can know about fetching Modes, but it's throwing a exception, Please make a look at the code.
public class State {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
String name;
@OneToMany(mappedBy = "state", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
Set<Constituency> constituencies ;
public void fetchLazyCollection() {
getConstituencies().size();
}
}
public class Constituency {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
String name;
@ManyToOne
@JoinColumn(name = "state_id")
State state;
}
So, as you can see there are two classes State and Constituency and from State to Constituency one-to-many mapping exists and vice versa there is many-to-one. Please let me know if i have made any stupid mistake here.
@Test
public void delhiShouldHaveTwoConstituency(){
State delhi = new State();
delhi.setName("New Delhi");
Constituency northWest = new Constituency();
northWest.setName("North West");
northWest.setState(delhi);
Constituency southDelhi = new Constituency();
southDelhi.setName("South Delhi");
southDelhi.setState(delhi);
Set<Constituency> constituencies = new HashSet<Constituency>();
constituencies.add(northWest);
constituencies.add(southDelhi);
delhi.setConstituencies(constituencies);
stateRepository.save(delhi);
List<State> states= stateRepository.findByName("New Delhi");
states.get(0).fetchLazyCollection();
assertThat(delhi.getConstituencies().size(), is(2));
}
Now, i have a test which is saving a state with two of its constituencies and then i am trying to retrieve them again using :
List<State> states= stateRepository.findByName("New Delhi");
According to my understanding, i am assuming as this statement will execute, constituencies in State won't get initialize until next statement executes which is to invoke fetchLazyCollection but as fetchLazyCollection invokes it's throwing exception of
could not initialize Proxy - No Session
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.prateekj.model.State.constituencies, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:567)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:187)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:138)
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:156)
at com.prateekj.model.State.fetchLazyCollection(State.java:35)
at com.prateekj.repositories.StateRepositoryTest.shouldDoIt(StateRepositoryTest.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
as i am assuming, each unit tests in java maintain its own session of interaction with database, may be i am wrong, can anyone please tell me what wrong i have done here ? Any help will be appreciated.