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