HHH-12166 : test case
This commit is contained in:
parent
7bcfa0d90d
commit
05404eff0f
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.test.compositeusertype.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Line implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Point p1, p2;
|
||||
|
||||
public Line(Point p1, Point p2) {
|
||||
this.p1 = Objects.requireNonNull( p1 );
|
||||
this.p2 = Objects.requireNonNull( p2 );
|
||||
}
|
||||
|
||||
public Point getP1() {
|
||||
return p1;
|
||||
}
|
||||
|
||||
public Point getP2() {
|
||||
return p2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Line line = (Line) o;
|
||||
return Objects.equals( p1, line.p1 ) &&
|
||||
Objects.equals( p2, line.p2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( p1, p2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Line{" +
|
||||
"p1=" + p1 +
|
||||
", p2=" + p2 +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.test.compositeusertype.nested;
|
||||
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.Columns;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
@Entity
|
||||
public class LineEntity {
|
||||
private long id;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private Line line;
|
||||
|
||||
@Type(type = "org.hibernate.test.compositeusertype.nested.LineType")
|
||||
@Columns(columns = {
|
||||
@Column(name = "x1"),
|
||||
@Column(name = "y1"),
|
||||
@Column(name = "x2"),
|
||||
@Column(name = "y2")
|
||||
})
|
||||
public Line getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public void setLine(Line line) {
|
||||
this.line = line;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.test.compositeusertype.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
public class LineType implements CompositeUserType {
|
||||
|
||||
private static final String[] PROPERTY_NAMES = { "p1", "p2" };
|
||||
private static final Type[] PROPERTY_TYPES = { PointType.TYPE, PointType.TYPE };
|
||||
|
||||
@Override
|
||||
public String[] getPropertyNames() {
|
||||
return PROPERTY_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getPropertyTypes() {
|
||||
return PROPERTY_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPropertyValue(Object component, int property) throws HibernateException {
|
||||
switch ( property ) {
|
||||
case 0:
|
||||
return ( (Line) component ).getP1();
|
||||
case 1:
|
||||
return ( (Line) component ).getP2();
|
||||
default:
|
||||
throw new IndexOutOfBoundsException( "Invalid property index: " + property );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
|
||||
throw new UnsupportedOperationException( "Immutable type" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class returnedClass() {
|
||||
return Line.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object x, Object y) throws HibernateException {
|
||||
return Objects.equals( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(Object x) throws HibernateException {
|
||||
return Objects.hashCode( x );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
Point p1 = (Point) PointType.TYPE.nullSafeGet( rs, Arrays.copyOfRange( names, 0, 2 ), session, owner );
|
||||
Point p2 = (Point) PointType.TYPE.nullSafeGet( rs, Arrays.copyOfRange( names, 2, 4 ), session, owner );
|
||||
return p1 == null || p2 == null ? null : new Line( p1, p2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
if ( value == null ) {
|
||||
PointType.TYPE.nullSafeSet( st, null, index, session );
|
||||
PointType.TYPE.nullSafeSet( st, null, index + 2, session );
|
||||
}
|
||||
else {
|
||||
Line l = (Line) value;
|
||||
PointType.TYPE.nullSafeSet( st, l.getP1(), index, session );
|
||||
PointType.TYPE.nullSafeSet( st, l.getP2(), index + 2, session );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deepCopy(Object value) throws HibernateException {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException {
|
||||
return (Line) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return original;
|
||||
}
|
||||
}
|
|
@ -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.test.compositeusertype.nested;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
|
||||
public class NestedCompositeUserTypeTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
LineEntity.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-12166")
|
||||
public void testIt() {
|
||||
Line line = new Line( new Point( 0, 0 ), new Point( 42, 84 ) );
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
LineEntity le = new LineEntity();
|
||||
le.setLine( line );
|
||||
session.save( le );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
LineEntity lineEntry = session.createQuery( "from " + LineEntity.class.getName(), LineEntity.class )
|
||||
.uniqueResult();
|
||||
Assert.assertEquals( line, lineEntry.getLine() );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.test.compositeusertype.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Point implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final int x, y;
|
||||
|
||||
public Point(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Point point = (Point) o;
|
||||
return x == point.x &&
|
||||
y == point.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return x * 31 + y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Point{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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.test.compositeusertype.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.CompositeCustomType;
|
||||
import org.hibernate.type.IntegerType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
public class PointType implements CompositeUserType {
|
||||
public static final CompositeCustomType TYPE = new CompositeCustomType( new PointType() );
|
||||
|
||||
private static final String[] PROPERTY_NAMES = { "x", "y" };
|
||||
private static final Type[] PROPERTY_TYPES = { IntegerType.INSTANCE, IntegerType.INSTANCE };
|
||||
|
||||
@Override
|
||||
public String[] getPropertyNames() {
|
||||
return PROPERTY_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getPropertyTypes() {
|
||||
return PROPERTY_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPropertyValue(Object component, int property) throws HibernateException {
|
||||
switch ( property ) {
|
||||
case 0:
|
||||
return ( (Point) component ).getX();
|
||||
case 1:
|
||||
return ( (Point) component ).getY();
|
||||
default:
|
||||
throw new IndexOutOfBoundsException( "Invalid property index: " + property );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
|
||||
throw new UnsupportedOperationException( "Immutable type" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class returnedClass() {
|
||||
return Point.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object x, Object y) throws HibernateException {
|
||||
return Objects.equals( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(Object x) throws HibernateException {
|
||||
return Objects.hashCode( x );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
int x = rs.getInt( names[0] );
|
||||
boolean xNull = rs.wasNull();
|
||||
int y = rs.getInt( names[1] );
|
||||
boolean yNull = rs.wasNull();
|
||||
return xNull || yNull ? null : new Point( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
if ( value == null ) {
|
||||
st.setNull( index, Types.INTEGER );
|
||||
st.setNull( index + 1, Types.INTEGER );
|
||||
}
|
||||
else {
|
||||
Point p = (Point) value;
|
||||
st.setInt( index, p.getX() );
|
||||
st.setInt( index + 1, p.getY() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deepCopy(Object value) throws HibernateException {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException {
|
||||
return (Point) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return original;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue