简体   繁体   English

懒惰获取的一对一关系

[英]One-To-One relation with lazy fetch

In our java application we have two entities: A main account and the settings for this account. 在我们的Java应用程序中,我们有两个实体:一个主帐户和该帐户的设置。 We use hibernate for providing persistence. 我们使用休眠来提供持久性。 We want the account settings to be lazy loaded. 我们希望帐户设置可以延迟加载。 So we did this: 所以我们这样做:

AccountMain: 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: 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. 当我们在AccountMain中加载AccountMainSettings对象时,该对象将被正确代理。 But when we call a method of AccountMainSettings, the object is not loaded from the database an an NPE is thown of course. 但是,当我们调用AccountMainSettings方法时,不会从数据库中加载对象,当然会抛出NPE。 Having read Making-a-onetoone-relation-lazy didn't help much. 阅读懒惰的“ oneoneone关系”并没有多大帮助。 We neither have a nullable association nor do we want to convert it to a ManyToOne association. 我们既没有可为空的关联,也不想将其转换为ManyToOne关联。 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: 更新:这是我们的jUnit测试:

@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: 和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)

Getter shouldn't be final. 吸气剂不应该是最终的。 And use @JoinColumn annotation on field, not on getter. 并在字段而不是getter上使用@JoinColumn批注。 Or use all mapping for getter, then you should add @Access(AccessType.PROPERTY) 或将所有映射用于吸气剂,然后应添加@Access(AccessType.PROPERTY)

I have this and it works for me in my code. 我有这个,它对我的​​代码有效。

@JoinColumn(name = "contract_id", referencedColumnName = "id")
@OneToOne(fetch = FetchType.LAZY)
private Contract contract;

Are you missing the referencedColumnName in your code? 您是否在代码中缺少referencedColumnName? you are specifying the name of the join column but not the name of the column on the other side of the relationship 您指定的是连接列的名称,而不是关系另一侧的列的名称

Note all my annotations are on the field and my getter and setter are just plain old getters and setters in this class 请注意,我所有的注释都在该字段上,而我的getter和setter只是该类中的普通旧getter和setters

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM