Skip to content

HHH-15045 + HHH-15235 #5330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
/**
* Resolve an identifier or unique key value
*/
private Object resolve(Object value, SharedSessionContractImplementor session, Object owner) {
protected Object resolve(Object value, SharedSessionContractImplementor session, Object owner) {
if ( value != null && !isNull( owner, session ) ) {
if ( isReferenceToPrimaryKey() ) {
return resolveIdentifier( value, session, null );
Expand Down
45 changes: 14 additions & 31 deletions hibernate-core/src/main/java/org/hibernate/type/OneToOneType.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,12 @@ public boolean isOneToOne() {

@Override
public boolean isDirty(Object old, Object current, SharedSessionContractImplementor session) {
if ( isSame( old, current ) ) {
return false;
}

return getIdentifierType( session )
.isDirty( getIdentifier( old, session ), getIdentifier( current, session ), session );
return false;
}

@Override
public boolean isDirty(Object old, Object current, boolean[] checkable, SharedSessionContractImplementor session) {
return isDirty(old, current, session);
return false;
}

@Override
Expand All @@ -141,37 +136,25 @@ public boolean useLHSPrimaryKey() {

@Override
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner) throws HibernateException {
if (value == null) {
return null;
}

Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session );

if ( id == null ) {
throw new AssertionFailure(
"cannot cache a reference to an object with a null id: " +
getAssociatedEntityName()
);
}

return getIdentifierType( session ).disassemble( id, session, owner );
return null;
}

@Override
public Object assemble(Serializable oid, SharedSessionContractImplementor session, Object owner) throws HibernateException {

//the owner of the association is not the owner of the id
Object id = getIdentifierType( session ).assemble( oid, session, null );

if ( id == null ) {
return null;
}

return resolveIdentifier( id, session );
//this should be a call to resolve(), not resolveIdentifier(),
//'cos it might be a property-ref, and we did not cache the
//referenced value
return resolve( session.getContextEntityIdentifier(owner), session, owner );
}

/**
* We don't need to dirty check one-to-one because of how
* assemble/disassemble is implemented and because a one-to-one
* association is never dirty
*/
@Override
public boolean isAlwaysDirtyChecked() {
return true;
//TODO: this is kinda inconsistent with CollectionType
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.onetoone;

import java.io.Serializable;

import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;

import org.junit.jupiter.api.Test;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;

@TestForIssue(jiraKey = "HHH-15235")
@DomainModel(
annotatedClasses = {
EmbeddedIdTest.Bar.class,
EmbeddedIdTest.Foo.class
}
)
@SessionFactory
public class EmbeddedIdTest {

@Test
public void testMerge(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
FooId fooId = new FooId();
fooId.id = "foo";
Foo foo = new Foo();
foo.id = fooId;
Bar bar = new Bar();
BarId barId = new BarId();
barId.id = 1l;
bar.id = barId;
foo.bar = bar;
bar.foo = foo;
session.merge( foo );
session.flush();
}
);
}

@Embeddable
public static class BarId implements Serializable {
private Long id;
}

@Embeddable
public static class FooId implements Serializable {
private String id;
}

@Entity(name = "Bar")
@Table(name = "BAR_TABLE")
public static class Bar {
@EmbeddedId
private BarId id;

private String name;

@OneToOne(mappedBy = "bar")
private Foo foo;
}

@Entity(name = "Foo")
@Table(name = "FOO_TABLE")
public static class Foo {
@EmbeddedId
private FooId id;

private String name;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "bar_id")
private Bar bar;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0"?>

<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping default-lazy="false" package="org.hibernate.orm.test.onetoone.cache">
<class name="MainObject" table="mainobject">
<cache usage="read-write"/>

<id name="id" column="id" type="java.lang.Long">
<generator class="native">
<param name="sequence">seq_mainobj</param>
</generator>
</id>

<one-to-one name="obj2" class="Object2" cascade="all" outer-join="auto"/>

<property name="description" type="java.lang.String" update="true" insert="true" column="description" />

</class>

</hibernate-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.onetoone.cache;


/**
* @author Wolfgang Voelkl
*/
public class MainObject {
private Long id;
private String description;
private Object2 obj2;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Object2 getObj2() {
return obj2;
}

public String getDescription() {
return description;
}

public void setDescription(String string) {
description = string;
}

public void setObj2(Object2 object2) {
this.obj2 = object2;
if (object2 != null) {
object2.setBelongsToMainObj(this);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0"?>

<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping default-lazy="false" package="org.hibernate.orm.test.onetoone.cache">
<class name="Object2" table="object2">
<cache usage="read-write"/>

<id name="id" column="id" type="java.lang.Long">
<generator class="foreign">
<param name="property">belongsToMainObj</param>
</generator>
</id>

<property name="dummy" type="java.lang.String" update="true" insert="true" column="xdummy"/>

<one-to-one name="belongsToMainObj" class="MainObject" cascade="none" outer-join="auto" constrained="true"/>
</class>

</hibernate-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.onetoone.cache;


/**
*
* @author Wolfgang Voelkl
*
*/
public class Object2 {
private Long id;
private String dummy;
private MainObject belongsToMainObj;

public Long getId() {
return id;
}

public void setId(Long l) {
this.id = l;
}

public String getDummy() {
return dummy;
}

public void setDummy(String string) {
dummy = string;
}

public MainObject getBelongsToMainObj() {
return belongsToMainObj;
}

public void setBelongsToMainObj(MainObject object) {
belongsToMainObj = object;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.hibernate.stat.spi.StatisticsImplementor;

import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
Expand Down Expand Up @@ -120,6 +121,7 @@ private <TPerson extends Person> List<TPerson> getPersons(
}

@Test
@FailureExpected( jiraKey = "HHH-14216", reason = "The changes introduces by HHH-14216 have been reverted see https://github.com/hibernate/hibernate-orm/pull/5061 discussion")
public void OneToOneCacheByForeignKey(SessionFactoryScope scope) throws Exception {
OneToOneTest( PersonByFK.class, DetailsByFK.class, scope );
}
Expand Down
Loading