HHH-5946 - Wrong SQL generated when composites are compared using not-equal operator
This commit is contained in:
parent
4132a4293a
commit
cd2b031b6b
|
@ -12,6 +12,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.TypeMismatchException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
|
||||
import org.hibernate.hql.internal.ast.QuerySyntaxException;
|
||||
import org.hibernate.hql.internal.ast.util.ColumnHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.param.ParameterSpecification;
|
||||
|
@ -110,8 +111,22 @@ public class BinaryLogicOperatorNode extends AbstractSelectExpression implements
|
|||
// mutation depends on the types of nodes involved...
|
||||
int comparisonType = getType();
|
||||
String comparisonText = getText();
|
||||
setType( HqlSqlTokenTypes.AND );
|
||||
setText( "AND" );
|
||||
|
||||
switch ( comparisonType ) {
|
||||
case HqlSqlTokenTypes.EQ:
|
||||
setType( HqlSqlTokenTypes.AND );
|
||||
setText( "AND" );
|
||||
break;
|
||||
|
||||
case HqlSqlTokenTypes.NE:
|
||||
setType( HqlSqlTokenTypes.OR );
|
||||
setText( "OR" );
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new QuerySyntaxException( comparisonText + " operator not supported on composite types." );
|
||||
}
|
||||
|
||||
String[] lhsElementTexts = extractMutationTexts( getLeftHandOperand(), valueElements );
|
||||
String[] rhsElementTexts = extractMutationTexts( getRightHandOperand(), valueElements );
|
||||
|
||||
|
@ -175,7 +190,7 @@ public class BinaryLogicOperatorNode extends AbstractSelectExpression implements
|
|||
AST rhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[i] );
|
||||
op.setFirstChild( lhs );
|
||||
lhs.setNextSibling( rhs );
|
||||
AST newContainer = getASTFactory().create( HqlSqlTokenTypes.AND, "AND" );
|
||||
AST newContainer = getASTFactory().create( container.getType(), container.getText() );
|
||||
container.setFirstChild( newContainer );
|
||||
newContainer.setNextSibling( op );
|
||||
container = newContainer;
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.cut;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class for testing composite user types with more than two fields.
|
||||
*
|
||||
* @author Etienne Miret
|
||||
*/
|
||||
public class CompositeDateTime implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7401750071679578453L;
|
||||
|
||||
private Integer year;
|
||||
|
||||
private Integer month;
|
||||
|
||||
private Integer day;
|
||||
|
||||
private Integer hour;
|
||||
|
||||
private Integer minute;
|
||||
|
||||
private Integer second;
|
||||
|
||||
public CompositeDateTime(final Integer year, final Integer month, final Integer day, final Integer hour,
|
||||
final Integer minute, final Integer second) {
|
||||
super();
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
this.hour = hour;
|
||||
this.minute = minute;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for those who hate auto (un)boxing.
|
||||
*/
|
||||
public CompositeDateTime(final int year, final int month, final int day, final int hour,
|
||||
final int minute, final int second) {
|
||||
this( new Integer( year ), Integer.valueOf( month ), Integer.valueOf( day ), Integer.valueOf( hour ),
|
||||
Integer.valueOf( minute ), Integer.valueOf( second ) );
|
||||
}
|
||||
|
||||
public CompositeDateTime(final CompositeDateTime other) {
|
||||
super();
|
||||
this.year = other.year;
|
||||
this.month = other.month;
|
||||
this.day = other.day;
|
||||
this.hour = other.hour;
|
||||
this.minute = other.minute;
|
||||
this.second = other.second;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(final Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public Integer getMonth() {
|
||||
return month;
|
||||
}
|
||||
|
||||
public void setMonth(final Integer month) {
|
||||
this.month = month;
|
||||
}
|
||||
|
||||
public Integer getDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
public void setDay(final Integer day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
public Integer getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
public void setHour(final Integer hour) {
|
||||
this.hour = hour;
|
||||
}
|
||||
|
||||
public Integer getMinute() {
|
||||
return minute;
|
||||
}
|
||||
|
||||
public void setMinute(final Integer minute) {
|
||||
this.minute = minute;
|
||||
}
|
||||
|
||||
public Integer getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
public void setSecond(final Integer second) {
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ( ( day == null ) ? 0 : day.hashCode() );
|
||||
result = prime * result + ( ( hour == null ) ? 0 : hour.hashCode() );
|
||||
result = prime * result + ( ( minute == null ) ? 0 : minute.hashCode() );
|
||||
result = prime * result + ( ( month == null ) ? 0 : month.hashCode() );
|
||||
result = prime * result + ( ( second == null ) ? 0 : second.hashCode() );
|
||||
result = prime * result + ( ( year == null ) ? 0 : year.hashCode() );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( this == obj ) {
|
||||
return true;
|
||||
}
|
||||
if ( obj == null ) {
|
||||
return false;
|
||||
}
|
||||
if ( !( obj instanceof CompositeDateTime ) ) {
|
||||
return false;
|
||||
}
|
||||
CompositeDateTime other = (CompositeDateTime) obj;
|
||||
if ( day == null ) {
|
||||
if ( other.day != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !day.equals( other.day ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( hour == null ) {
|
||||
if ( other.hour != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !hour.equals( other.hour ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( minute == null ) {
|
||||
if ( other.minute != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !minute.equals( other.minute ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( month == null ) {
|
||||
if ( other.month != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !month.equals( other.month ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( second == null ) {
|
||||
if ( other.second != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !second.equals( other.second ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( year == null ) {
|
||||
if ( other.year != null ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !year.equals( other.year ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.cut;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
/**
|
||||
* Class for testing composite user types with more than two fields.
|
||||
*
|
||||
* @author Etienne Miret
|
||||
*/
|
||||
public class CompositeDateTimeUserType implements CompositeUserType {
|
||||
|
||||
@Override
|
||||
public String[] getPropertyNames() {
|
||||
return new String[] { "year", "month", "day", "hour", "minute", "second" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getPropertyTypes() {
|
||||
return new Type[] { StandardBasicTypes.INTEGER, StandardBasicTypes.INTEGER, StandardBasicTypes.INTEGER,
|
||||
StandardBasicTypes.INTEGER, StandardBasicTypes.INTEGER, StandardBasicTypes.INTEGER };
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPropertyValue(Object component, int property) throws HibernateException {
|
||||
final CompositeDateTime dateTime = (CompositeDateTime) component;
|
||||
switch ( property ) {
|
||||
case 0:
|
||||
return dateTime.getYear();
|
||||
|
||||
case 1:
|
||||
return dateTime.getMonth();
|
||||
|
||||
case 2:
|
||||
return dateTime.getDay();
|
||||
|
||||
case 3:
|
||||
return dateTime.getHour();
|
||||
|
||||
case 4:
|
||||
return dateTime.getMinute();
|
||||
|
||||
case 5:
|
||||
return dateTime.getSecond();
|
||||
|
||||
default:
|
||||
throw new HibernateException( "This type has only 6 fields." );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<CompositeDateTime> returnedClass() {
|
||||
return CompositeDateTime.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object x, Object y) throws HibernateException {
|
||||
return x == null ? y == null : x.equals( y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(Object x) throws HibernateException {
|
||||
return x == null ? 0 : x.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
|
||||
final Integer year = rs.getObject( names[0], Integer.class );
|
||||
final Integer month = rs.getObject( names[1], Integer.class );
|
||||
final Integer day = rs.getObject( names[2], Integer.class );
|
||||
final Integer hour = rs.getObject( names[3], Integer.class );
|
||||
final Integer minute = rs.getObject( names[4], Integer.class );
|
||||
final Integer second = rs.getObject( names[5], Integer.class );
|
||||
if ( year == null && month == null && day == null && hour == null && minute == null && second == null ) {
|
||||
return null;
|
||||
} else {
|
||||
return new CompositeDateTime( year, month, day, hour, minute, second );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
|
||||
if ( value == null ) {
|
||||
for (int i = 0; i < 6; i++ ) {
|
||||
st.setObject( index + i, null );
|
||||
}
|
||||
} else {
|
||||
final CompositeDateTime dateTime = (CompositeDateTime) value;
|
||||
st.setObject( index, dateTime.getYear() );
|
||||
st.setObject( index + 1, dateTime.getMonth() );
|
||||
st.setObject( index + 2, dateTime.getDay() );
|
||||
st.setObject( index + 3, dateTime.getHour() );
|
||||
st.setObject( index + 4, dateTime.getMinute() );
|
||||
st.setObject( index + 5, dateTime.getSecond() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeDateTime deepCopy(Object value) throws HibernateException {
|
||||
return value == null ? null : new CompositeDateTime( (CompositeDateTime) value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException {
|
||||
return deepCopy( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException {
|
||||
return deepCopy( cached );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replace(Object original, Object target, SessionImplementor session, Object owner) throws HibernateException {
|
||||
return deepCopy( original );
|
||||
}
|
||||
|
||||
}
|
|
@ -11,13 +11,16 @@ import java.math.BigDecimal;
|
|||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.SybaseASE15Dialect;
|
||||
import org.hibernate.hql.internal.ast.QuerySyntaxException;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.SkipForDialects;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -52,7 +55,8 @@ public class CompositeUserTypeTest extends BaseCoreFunctionalTestCase {
|
|||
assertEquals( result.size(), 1 );
|
||||
result = s.createQuery("from Transaction where value = (1.5, 'AUD')").list();
|
||||
assertEquals( result.size(), 1 );
|
||||
|
||||
result = s.createQuery( "from Transaction where value != (1.4, 'AUD')" ).list();
|
||||
assertEquals( result.size(), 1 );
|
||||
}
|
||||
|
||||
s.delete(tran);
|
||||
|
@ -102,5 +106,185 @@ public class CompositeUserTypeTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Tests the {@code =} operator on composite types.
|
||||
*/
|
||||
public void testEqualOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Transaction txn = new Transaction();
|
||||
txn.setDescription( "foo" );
|
||||
txn.setValue( new MonetoryAmount( new BigDecimal( 42 ), Currency.getInstance( "AUD" ) ) );
|
||||
txn.setTimestamp( new CompositeDateTime( 2014, 8, 23, 14, 35, 0 ) );
|
||||
s.persist( txn );
|
||||
|
||||
final Query q = s.createQuery( "from Transaction where value = :amount" );
|
||||
|
||||
/* Both amount and currency match. */
|
||||
q.setParameter( "amount", new MonetoryAmount( new BigDecimal( 42 ), Currency.getInstance( "AUD" ) ) );
|
||||
assertEquals( 1, q.list().size() );
|
||||
|
||||
/* Only currency matches. */
|
||||
q.setParameter( "amount", new MonetoryAmount( new BigDecimal( 36 ), Currency.getInstance( "AUD" ) ) );
|
||||
assertEquals( 0, q.list().size() );
|
||||
|
||||
/* Only amount matches. */
|
||||
q.setParameter( "amount", new MonetoryAmount( new BigDecimal( 42 ), Currency.getInstance( "EUR" ) ) );
|
||||
assertEquals( 0, q.list().size() );
|
||||
|
||||
/* None match. */
|
||||
q.setParameter( "amount", new MonetoryAmount( new BigDecimal( 76 ), Currency.getInstance( "USD" ) ) );
|
||||
assertEquals( 0, q.list().size() );
|
||||
|
||||
final Query qTimestamp = s.createQuery( "from Transaction where timestamp = :timestamp" );
|
||||
|
||||
/* All matches. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2014, 8, 23, 14, 35, 0 ) );
|
||||
assertEquals( 1, qTimestamp.list().size() );
|
||||
|
||||
/* None matches. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2013, 9, 25, 12, 31, 25 ) );
|
||||
assertEquals( 0, qTimestamp.list().size() );
|
||||
|
||||
/* Year doesn't match. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2013, 8, 23, 14, 35, 0 ) );
|
||||
assertEquals( 0, qTimestamp.list().size() );
|
||||
|
||||
/* Month doesn't match. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2014, 9, 23, 14, 35, 0 ) );
|
||||
assertEquals( 0, qTimestamp.list().size() );
|
||||
|
||||
/* Minute doesn't match. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2014, 8, 23, 14, 41, 0 ) );
|
||||
assertEquals( 0, qTimestamp.list().size() );
|
||||
|
||||
/* Second doesn't match. */
|
||||
qTimestamp.setParameter( "timestamp", new CompositeDateTime( 2014, 8, 23, 14, 35, 28 ) );
|
||||
assertEquals( 0, qTimestamp.list().size() );
|
||||
|
||||
s.delete( txn );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@code <>} operator on composite types.
|
||||
*/
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-5946" )
|
||||
public void testNotEqualOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Transaction t1 = new Transaction();
|
||||
t1.setDescription( "foo" );
|
||||
t1.setValue( new MonetoryAmount( new BigDecimal( 178 ), Currency.getInstance( "EUR" ) ) );
|
||||
t1.setTimestamp( new CompositeDateTime( 2014, 8, 23, 14, 23, 0 ) );
|
||||
s.persist( t1 );
|
||||
|
||||
final Transaction t2 = new Transaction();
|
||||
t2.setDescription( "bar" );
|
||||
t2.setValue( new MonetoryAmount( new BigDecimal( 1000000 ), Currency.getInstance( "USD" ) ) );
|
||||
t1.setTimestamp( new CompositeDateTime( 2014, 8, 22, 14, 23, 0 ) );
|
||||
s.persist( t2 );
|
||||
|
||||
final Transaction t3 = new Transaction();
|
||||
t3.setDescription( "bar" );
|
||||
t3.setValue( new MonetoryAmount( new BigDecimal( 1000000 ), Currency.getInstance( "EUR" ) ) );
|
||||
t3.setTimestamp( new CompositeDateTime( 2014, 8, 22, 14, 23, 01 ) );
|
||||
s.persist( t3 );
|
||||
|
||||
final Query q1 = s.createQuery( "from Transaction where value <> :amount" );
|
||||
q1.setParameter( "amount", new MonetoryAmount( new BigDecimal( 178 ), Currency.getInstance( "EUR" ) ) );
|
||||
assertEquals( 2, q1.list().size() );
|
||||
|
||||
final Query q2 = s.createQuery( "from Transaction where value <> :amount and description = :str" );
|
||||
q2.setParameter( "amount", new MonetoryAmount( new BigDecimal( 1000000 ), Currency.getInstance( "USD" ) ) );
|
||||
q2.setParameter( "str", "bar" );
|
||||
assertEquals( 1, q2.list().size() );
|
||||
|
||||
final Query q3 = s.createQuery( "from Transaction where timestamp <> :timestamp" );
|
||||
q3.setParameter( "timestamp", new CompositeDateTime( 2014, 8, 23, 14, 23, 0 ) );
|
||||
assertEquals( 2, q3.list().size() );
|
||||
|
||||
s.delete( t3 );
|
||||
s.delete( t2 );
|
||||
s.delete( t1 );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@code <} operator on composite types. As long as we don't support it, we need to throw an exception
|
||||
* rather than create a random query.
|
||||
*/
|
||||
@Test( expected = QuerySyntaxException.class )
|
||||
@TestForIssue( jiraKey = "HHH-5946" )
|
||||
public void testLessThanOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Query q = s.createQuery( "from Transaction where value < :amount" );
|
||||
q.setParameter( "amount", new MonetoryAmount( BigDecimal.ZERO, Currency.getInstance( "EUR" ) ) );
|
||||
q.list();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@code <=} operator on composite types. As long as we don't support it, we need to throw an exception
|
||||
* rather than create a random query.
|
||||
*/
|
||||
@Test( expected = QuerySyntaxException.class )
|
||||
@TestForIssue( jiraKey = "HHH-5946" )
|
||||
public void testLessOrEqualOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Query q = s.createQuery( "from Transaction where value <= :amount" );
|
||||
q.setParameter( "amount", new MonetoryAmount( BigDecimal.ZERO, Currency.getInstance( "USD" ) ) );
|
||||
q.list();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@code >} operator on composite types. As long as we don't support it, we need to throw an exception
|
||||
* rather than create a random query.
|
||||
*/
|
||||
@Test( expected = QuerySyntaxException.class )
|
||||
@TestForIssue( jiraKey = "HHH-5946" )
|
||||
public void testGreaterThanOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Query q = s.createQuery( "from Transaction where value > :amount" );
|
||||
q.setParameter( "amount", new MonetoryAmount( BigDecimal.ZERO, Currency.getInstance( "EUR" ) ) );
|
||||
q.list();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@code >=} operator on composite types. As long as we don't support it, we need to throw an exception
|
||||
* rather than create a random query.
|
||||
*/
|
||||
@Test( expected = QuerySyntaxException.class )
|
||||
@TestForIssue( jiraKey = "HHH-5946" )
|
||||
public void testGreaterOrEqualOperator() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
final Query q = s.createQuery( "from Transaction where value >= :amount" );
|
||||
q.setParameter( "amount", new MonetoryAmount( BigDecimal.ZERO, Currency.getInstance( "USD" ) ) );
|
||||
q.list();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,14 @@
|
|||
<column name="amount" not-null="true"/>
|
||||
<column name="currency" not-null="true"/>
|
||||
</property>
|
||||
<property name="timestamp" type="userDateTime">
|
||||
<column name="year"/>
|
||||
<column name="month"/>
|
||||
<column name="day"/>
|
||||
<column name="hour"/>
|
||||
<column name="minute"/>
|
||||
<column name="second"/>
|
||||
</property>
|
||||
</class>
|
||||
|
||||
<class name="MutualFund" table="MutualFund">
|
||||
|
|
|
@ -17,7 +17,8 @@ public class Transaction {
|
|||
private Long id;
|
||||
private String description;
|
||||
private MonetoryAmount value;
|
||||
|
||||
private CompositeDateTime timestamp;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
@ -42,4 +43,12 @@ public class Transaction {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
public CompositeDateTime getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(CompositeDateTime timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,4 +11,5 @@
|
|||
|
||||
<hibernate-mapping package="org.hibernate.test.cut">
|
||||
<typedef name="money" class="org.hibernate.test.cut.MonetoryAmountUserType"/>
|
||||
</hibernate-mapping>
|
||||
<typedef name="userDateTime" class="org.hibernate.test.cut.CompositeDateTimeUserType"/>
|
||||
</hibernate-mapping>
|
||||
|
|
|
@ -1441,11 +1441,6 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
|||
s.createQuery( "from Human h where ('John', 'X', 'Doe') = h.name" ).list();
|
||||
s.createQuery( "from Human h where ('John', 'X', 'Doe') <> h.name" ).list();
|
||||
|
||||
// HANA only allows '=' and '<>'/'!='
|
||||
if ( ! ( getDialect() instanceof AbstractHANADialect ) ) {
|
||||
s.createQuery( "from Human h where ('John', 'X', 'Doe') >= h.name" ).list();
|
||||
}
|
||||
|
||||
s.createQuery( "from Human h order by h.name" ).list();
|
||||
|
||||
s.getTransaction().commit();
|
||||
|
|
Loading…
Reference in New Issue