HHH-4459 Query with Composite Primary Key parameter crashes when query
cache is on
This commit is contained in:
parent
199ee7860e
commit
58fa4c2eac
|
@ -100,7 +100,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
|
|||
if ( component == BackrefPropertyAccessor.UNKNOWN ) {
|
||||
return new Object[propertySpan];
|
||||
}
|
||||
if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||
else if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||
return optimizer.getAccessOptimizer().getPropertyValues( component );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -425,7 +425,15 @@ public class ComponentType extends AbstractType implements CompositeType, Proced
|
|||
|
||||
public Object[] getPropertyValues(Object component, EntityMode entityMode)
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.stat.EntityStatistics;
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
|
@ -41,19 +45,31 @@ import org.hibernate.testing.RequiresDialectFeature;
|
|||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.transform.Transformers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public class QueryCacheTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
private static final CompositeKey PK = new CompositeKey(1, 2);
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "querycache/Item.hbm.xml" };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
CompositeKey.class,
|
||||
EntityWithCompositeKey.class,
|
||||
StringCompositeKey.class,
|
||||
EntityWithStringCompositeKey.class
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
|
@ -431,6 +447,52 @@ public class QueryCacheTest extends BaseCoreFunctionalTestCase {
|
|||
assertEquals( qs.getExecutionCount(), 3 );
|
||||
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