In our java application we have two entities: A main account and the settings for this account. We use hibernate for providing persistence. We want the account settings to be lazy loaded. So we did this:
AccountMain:
@OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private AccountMainSettings accountMainSettings;
@JoinColumn(name = AccountMainSettings.ACCOUNT_MAIN_SETTINGS_ID, unique = true, nullable = false, updatable = false, insertable = true)
public final AccountMainSettings getAccountMainSettings() {
return this.accountMainSettings;
}
AccountMainSettings:
@OneToOne(mappedBy = "accountMainSettings")
private AccountMain accountMain;
public final AccountMain getAccountMain() {
return this.accountMain;
}
When we load the AccountMainSettings object in AccountMain it is proxied as it should be. But when we call a method of AccountMainSettings, the object is not loaded from the database an an NPE is thown of course. Having read Making-a-onetoone-relation-lazy didn't help much. We neither have a nullable association nor do we want to convert it to a ManyToOne association. When we switch to eager loading the problem is "solved", as the settings are loaded but they contain many fields so we don't want them to be unnecessarily loaded.
How can we implement lazy loading in this context?
Update: Here our jUnit Test:
@Test
public final void getMainAccountByAccountId() {
final AccountMain accountMain = this.accountMainDAO.getMainAccountByAccountId(PersistTestCaseConstants.SAVED_MAIN_ACCOUNT_ID);
final AccountMainSettings accountMainSettings = accountMain.getAccountMainSettings();
final String imprint = accountMainSettings.getImprint();
assertEquals(PersistTestCaseConstants.OBJECT_SUCESSFUL_ADDED, imprint.length(), 1000);
}
And the Stacktrace:
java.lang.NullPointerException
at com.persolog.eport.service.dao.AccountMainDAOTest.getMainAccountByAccountId(AccountMainDAOTest.java:418)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
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:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)