HHH-12166 : test case

This commit is contained in:
Gail Badner 2018-03-29 17:28:07 -07:00
parent 7bcfa0d90d
commit 05404eff0f
6 changed files with 439 additions and 0 deletions

View File

@ -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 +
'}';
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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() );
}
);
}
}

View File

@ -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 +
'}';
}
}

View File

@ -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;
}
}