HHH-16015 Add test for issue
This commit is contained in:
parent
664b10abc3
commit
7aea8723f2
|
@ -0,0 +1,39 @@
|
||||||
|
package org.hibernate.orm.test.mapping.embeddable.strategy.usertype.embedded.merge;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.CompositeType;
|
||||||
|
|
||||||
|
import jakarta.persistence.AttributeOverride;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Embedded;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Child {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
protected Long id;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
@AttributeOverride(name = "id", column = @Column(name = "value_id"))
|
||||||
|
@AttributeOverride(name = "hash", column = @Column(name = "value_hash"))
|
||||||
|
@CompositeType(MyCompositeValueType.class)
|
||||||
|
private MyCompositeValue compositeValue = new MyCompositeValue();
|
||||||
|
|
||||||
|
public Child() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Child(MyCompositeValue compositeValue) {
|
||||||
|
this.compositeValue = compositeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyCompositeValue getCompositeValue() {
|
||||||
|
return compositeValue;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.hibernate.orm.test.mapping.embeddable.strategy.usertype.embedded.merge;
|
||||||
|
|
||||||
|
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 static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
|
||||||
|
@DomainModel(
|
||||||
|
annotatedClasses = { Parent.class, Child.class }
|
||||||
|
)
|
||||||
|
@SessionFactory
|
||||||
|
@TestForIssue(jiraKey = "HHH-16015")
|
||||||
|
public class MergeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMerge(SessionFactoryScope scope) {
|
||||||
|
final Parent parent = new Parent( 1l, "Lio" );
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Child child = new Child( new MyCompositeValue( 2l, "initial value" ) );
|
||||||
|
parent.setChild( child );
|
||||||
|
session.persist( parent );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Child child = new Child( new MyCompositeValue( 1l, "updated value" ) );
|
||||||
|
parent.setChild( child );
|
||||||
|
|
||||||
|
session.merge( parent );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Parent lio = session.get( Parent.class, 1 );
|
||||||
|
Child child = lio.getChild();
|
||||||
|
|
||||||
|
assertThat( child ).isNotNull();
|
||||||
|
MyCompositeValue compositeValue = child.getCompositeValue();
|
||||||
|
assertThat( compositeValue ).isNotNull();
|
||||||
|
assertThat( compositeValue.stringValue() ).isEqualTo( "updated value" );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.hibernate.orm.test.mapping.embeddable.strategy.usertype.embedded.merge;
|
||||||
|
|
||||||
|
public class MyCompositeValue {
|
||||||
|
protected Long longValue;
|
||||||
|
protected String stringValue;
|
||||||
|
|
||||||
|
public MyCompositeValue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyCompositeValue(Long longValue, String stringValue) {
|
||||||
|
this.longValue = longValue;
|
||||||
|
this.stringValue = stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long longValue() {
|
||||||
|
return longValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String stringValue() {
|
||||||
|
return stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package org.hibernate.orm.test.mapping.embeddable.strategy.usertype.embedded.merge;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.spi.ValueAccess;
|
||||||
|
import org.hibernate.usertype.CompositeUserType;
|
||||||
|
|
||||||
|
public class MyCompositeValueType implements CompositeUserType<MyCompositeValue> {
|
||||||
|
public static class EmbeddableMapper {
|
||||||
|
Long longValue;
|
||||||
|
String stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPropertyValue(MyCompositeValue component, int property) throws HibernateException {
|
||||||
|
switch ( property ) {
|
||||||
|
case 0:
|
||||||
|
return component.longValue();
|
||||||
|
case 1:
|
||||||
|
return component.stringValue();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyCompositeValue instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
|
||||||
|
final Long id = values.getValue( 0, Long.class );
|
||||||
|
final String hash = values.getValue( 1, String.class );
|
||||||
|
return new MyCompositeValue( id, hash );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> embeddable() {
|
||||||
|
return EmbeddableMapper.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<MyCompositeValue> returnedClass() {
|
||||||
|
return MyCompositeValue.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(MyCompositeValue x, MyCompositeValue y) {
|
||||||
|
return Objects.equals( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(MyCompositeValue x) {
|
||||||
|
return Objects.hashCode( x );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyCompositeValue deepCopy(MyCompositeValue value) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new MyCompositeValue( value.longValue(), value.stringValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(MyCompositeValue value) {
|
||||||
|
return new Object[] { value.longValue(), value.stringValue() };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyCompositeValue assemble(Serializable cached, Object owner) {
|
||||||
|
final Object[] parts = (Object[]) cached;
|
||||||
|
return new MyCompositeValue( (Long) parts[0], (String) parts[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyCompositeValue replace(MyCompositeValue detached, MyCompositeValue managed, Object owner) {
|
||||||
|
return deepCopy( detached );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.hibernate.orm.test.mapping.embeddable.strategy.usertype.embedded.merge;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Parent {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
protected Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
|
private Child child;
|
||||||
|
|
||||||
|
public Parent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parent(Long id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Child getChild() {
|
||||||
|
return this.child;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChild(Child child) {
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue