HHH-4459 Query with Composite Primary Key parameter crashes when query
cache is on
This commit is contained in:
parent
95bc0194ec
commit
b130e7e430
|
@ -100,7 +100,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
|
||||||
if ( component == BackrefPropertyAccessor.UNKNOWN ) {
|
if ( component == BackrefPropertyAccessor.UNKNOWN ) {
|
||||||
return new Object[propertySpan];
|
return new Object[propertySpan];
|
||||||
}
|
}
|
||||||
if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
else if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||||
return optimizer.getAccessOptimizer().getPropertyValues( component );
|
return optimizer.getAccessOptimizer().getPropertyValues( component );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -424,7 +424,15 @@ public class ComponentType extends AbstractType implements CompositeType {
|
||||||
|
|
||||||
public Object[] getPropertyValues(Object component, EntityMode entityMode)
|
public Object[] getPropertyValues(Object component, EntityMode entityMode)
|
||||||
throws HibernateException {
|
throws HibernateException {
|
||||||
return componentTuplizer.getPropertyValues( component );
|
if ( component instanceof Object[] ) {
|
||||||
|
// A few calls to hashCode pass the property values already in an
|
||||||
|
// Object[] (ex: QueryKey hash codes for cached queries).
|
||||||
|
// It's easiest to just check for the condition here prior to
|
||||||
|
// trying reflection.
|
||||||
|
return ( Object[] ) component;
|
||||||
|
} else {
|
||||||
|
return componentTuplizer.getPropertyValues( component );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
|
public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.hibernate.test.querycache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public class CompositeKey implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 7950910288405475131L;
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
|
||||||
|
public int b;
|
||||||
|
|
||||||
|
public CompositeKey() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompositeKey(int a, int b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + a;
|
||||||
|
result = prime * result + b;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
CompositeKey other = (CompositeKey) obj;
|
||||||
|
if (a != other.a)
|
||||||
|
return false;
|
||||||
|
if (b != other.b)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.hibernate.test.querycache;
|
||||||
|
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EntityWithCompositeKey {
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
public CompositeKey pk;
|
||||||
|
|
||||||
|
public EntityWithCompositeKey() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithCompositeKey(CompositeKey pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.hibernate.test.querycache;
|
||||||
|
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Cache;
|
||||||
|
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||||
|
public class EntityWithStringCompositeKey {
|
||||||
|
|
||||||
|
private StringCompositeKey pk;
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
public StringCompositeKey getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPk(StringCompositeKey pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,17 +23,21 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.querycache;
|
package org.hibernate.test.querycache;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.hibernate.Criteria;
|
||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.Query;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.criterion.Restrictions;
|
||||||
import org.hibernate.stat.EntityStatistics;
|
import org.hibernate.stat.EntityStatistics;
|
||||||
import org.hibernate.stat.QueryStatistics;
|
import org.hibernate.stat.QueryStatistics;
|
||||||
import org.hibernate.testing.DialectChecks;
|
import org.hibernate.testing.DialectChecks;
|
||||||
|
@ -41,19 +45,31 @@ import org.hibernate.testing.RequiresDialectFeature;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
import org.hibernate.transform.Transformers;
|
import org.hibernate.transform.Transformers;
|
||||||
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
public class QueryCacheTest extends BaseCoreFunctionalTestCase {
|
public class QueryCacheTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
private static final CompositeKey PK = new CompositeKey(1, 2);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getMappings() {
|
public String[] getMappings() {
|
||||||
return new String[] { "querycache/Item.hbm.xml" };
|
return new String[] { "querycache/Item.hbm.xml" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {
|
||||||
|
CompositeKey.class,
|
||||||
|
EntityWithCompositeKey.class,
|
||||||
|
StringCompositeKey.class,
|
||||||
|
EntityWithStringCompositeKey.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Configuration cfg) {
|
public void configure(Configuration cfg) {
|
||||||
super.configure( cfg );
|
super.configure( cfg );
|
||||||
|
@ -431,6 +447,52 @@ public class QueryCacheTest extends BaseCoreFunctionalTestCase {
|
||||||
assertEquals( qs.getExecutionCount(), 3 );
|
assertEquals( qs.getExecutionCount(), 3 );
|
||||||
assertEquals( es.getFetchCount(), 0 ); //check that it was being cached
|
assertEquals( es.getFetchCount(), 0 ); //check that it was being cached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-4459" )
|
||||||
|
public void testGetByCompositeId() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
s.persist( new EntityWithCompositeKey( PK ) );
|
||||||
|
Query query = s.createQuery( "FROM EntityWithCompositeKey e WHERE e.pk = :pk" );
|
||||||
|
query.setCacheable( true );
|
||||||
|
query.setParameter( "pk", PK );
|
||||||
|
assertEquals(1, query.list().size( ));
|
||||||
|
s.getTransaction().rollback();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
EntityWithStringCompositeKey entity = new EntityWithStringCompositeKey();
|
||||||
|
StringCompositeKey key = new StringCompositeKey();
|
||||||
|
key.setAnalog( "foo1" );
|
||||||
|
key.setDevice( "foo2" );
|
||||||
|
key.setDeviceType( "foo3" );
|
||||||
|
key.setSubstation( "foo4" );
|
||||||
|
entity.setPk( key );
|
||||||
|
s.persist( entity );
|
||||||
|
Criteria c = s.createCriteria(
|
||||||
|
EntityWithStringCompositeKey.class ).add( Restrictions.eq(
|
||||||
|
"pk", key ) );
|
||||||
|
c.setCacheable( true );
|
||||||
|
assertEquals( 1, c.list().size() );
|
||||||
|
s.getTransaction().rollback();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void testGetByCompositeIdNoCache() {
|
||||||
|
// Query query = em.createQuery("FROM EntityWithCompositeKey e WHERE e.pk = :pk");
|
||||||
|
// query.setParameter("pk", PK);
|
||||||
|
// assertEquals(1, query.getResultList().size());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testGetByEntityIself() {
|
||||||
|
// Query query = em.createQuery("FROM EntityWithCompositeKey e WHERE e = :ent");
|
||||||
|
// query.setParameter("ent", new EntityWithCompositeKey(PK));
|
||||||
|
// assertEquals(1, query.getResultList().size());
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.hibernate.test.querycache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public class StringCompositeKey implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String substation;
|
||||||
|
|
||||||
|
private String deviceType;
|
||||||
|
|
||||||
|
private String device;
|
||||||
|
|
||||||
|
public String getSubstation() {
|
||||||
|
return substation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubstation(String substation) {
|
||||||
|
this.substation = substation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceType() {
|
||||||
|
return deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceType(String deviceType) {
|
||||||
|
this.deviceType = deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevice(String device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAnalog() {
|
||||||
|
return analog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnalog(String analog) {
|
||||||
|
this.analog = analog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String analog;
|
||||||
|
}
|
Loading…
Reference in New Issue