Skip to content

Commit b48f83b

Browse files
committed
HHH-6813 @id @OnetoOne cause NullPointerException during query
1 parent 66c15d3 commit b48f83b

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.hibernate.cfg.annotations.PropertyBinder;
3333
import org.hibernate.internal.util.StringHelper;
3434
import org.hibernate.mapping.Column;
35+
import org.hibernate.mapping.Component;
3536
import org.hibernate.mapping.DependantValue;
3637
import org.hibernate.mapping.Join;
3738
import org.hibernate.mapping.ManyToOne;
@@ -212,7 +213,23 @@ else if ( otherSideProperty.getValue() instanceof ManyToOne ) {
212213
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
213214
}
214215

215-
value.setReferencedPropertyName( mappedBy );
216+
// HHH-6813
217+
// If otherSide's id is derived, do not set EntityType#uniqueKeyPropertyName.
218+
// EntityType#isReferenceToPrimaryKey() assumes that, if it's set,
219+
// a PK is not referenced. Example:
220+
//
221+
// Foo: @Id long id, @OneToOne(mappedBy="foo") Bar bar
222+
// Bar: @Id @OneToOne Foo foo
223+
boolean referencesDerivedId = false;
224+
try {
225+
referencesDerivedId = otherSide.getIdentifier() instanceof Component
226+
&& ( (Component) otherSide.getIdentifier() ).getProperty( mappedBy ) != null;
227+
}
228+
catch ( MappingException e ) {
229+
// ignore
230+
}
231+
String referencedPropertyName = referencesDerivedId ? null : mappedBy;
232+
value.setReferencedPropertyName( referencedPropertyName );
216233

217234
String propertyRef = value.getReferencedPropertyName();
218235
if ( propertyRef != null ) {

hibernate-core/src/test/java/org/hibernate/test/annotations/derivedidentities/bidirectional/OneToOneWithDerivedIdentityTest.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
*/
2424
package org.hibernate.test.annotations.derivedidentities.bidirectional;
2525

26-
import org.junit.Test;
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertNotNull;
2728

2829
import org.hibernate.Session;
2930
import org.hibernate.testing.FailureExpected;
31+
import org.hibernate.testing.TestForIssue;
3032
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
31-
32-
import static org.junit.Assert.assertEquals;
33-
import static org.junit.Assert.assertNotNull;
33+
import org.junit.Test;
3434

3535
public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase {
3636
@Test
@@ -57,6 +57,29 @@ public void testInsertFooAndBarWithDerivedId() {
5757
s.getTransaction().rollback();
5858
s.close();
5959
}
60+
61+
@Test
62+
@TestForIssue(jiraKey = "HHH-6813")
63+
public void testSelectWithDerivedId() {
64+
Session s = openSession();
65+
s.beginTransaction();
66+
Bar bar = new Bar();
67+
bar.setDetails( "Some details" );
68+
Foo foo = new Foo();
69+
foo.setBar( bar );
70+
bar.setFoo( foo );
71+
s.persist( foo );
72+
s.flush();
73+
assertNotNull( foo.getId() );
74+
assertEquals( foo.getId(), bar.getFoo().getId() );
75+
76+
s.clear();
77+
Foo newFoo = (Foo) s.createQuery( "SELECT f FROM Foo f" ).uniqueResult();
78+
assertNotNull( newFoo );
79+
assertEquals( "Some details", newFoo.getBar().getDetails() );
80+
s.getTransaction().rollback();
81+
s.close();
82+
}
6083

6184
@Override
6285
protected Class<?>[] getAnnotatedClasses() {

0 commit comments

Comments
 (0)