HHH-3434 - hql insert doesn't work when inserting into a table with composite-id

This commit is contained in:
Andrei Badea 2011-10-18 11:49:30 +02:00 committed by Emmanuel Bernard
parent af2417cbaa
commit 09d40d1785
4 changed files with 116 additions and 4 deletions

View File

@ -26,11 +26,16 @@ package org.hibernate.hql.internal.ast.tree;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.QueryException;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.type.ComponentType;
import org.hibernate.type.Type;
import antlr.collections.AST;
/**
@ -49,6 +54,8 @@ public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
private boolean explicitIdInsertion;
private boolean explicitVersionInsertion;
private Set componentIds;
private List explicitComponentIds;
public void initialize(Queryable persister) {
if ( persister.isAbstract() ) {
@ -165,9 +172,26 @@ public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" );
}
if ( name.equals( persister.getIdentifierPropertyName() ) ) {
if ( !explicitIdInsertion ) {
if ( persister.getIdentifierType() instanceof ComponentType ) {
if ( componentIds == null ) {
String[] propertyNames = ( (ComponentType) persister.getIdentifierType() ).getPropertyNames();
componentIds = new HashSet();
for ( int i = 0; i < propertyNames.length; i++ ) {
componentIds.add( propertyNames[i] );
}
}
if ( componentIds.contains(name) ) {
if ( explicitComponentIds == null ) {
explicitComponentIds = new ArrayList( componentIds.size() );
}
explicitComponentIds.add( name );
explicitIdInsertion = explicitComponentIds.size() == componentIds.size();
}
} else if ( name.equals( persister.getIdentifierPropertyName() ) ) {
explicitIdInsertion = true;
}
}
if ( persister.isVersioned() ) {
if ( name.equals( persister.getPropertyNames()[ persister.getVersionProperty() ] ) ) {

View File

@ -65,7 +65,8 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
"legacy/Multi.hbm.xml",
"hql/EntityWithCrazyCompositeKey.hbm.xml",
"hql/SimpleEntityWithAssociation.hbm.xml",
"hql/BooleanLiteralEntity.hbm.xml"
"hql/BooleanLiteralEntity.hbm.xml",
"hql/CompositeIdEntity.hbm.xml"
};
}
@ -496,6 +497,18 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
s.close();
}
@Test
public void testInsertWithAssignedCompositeId() {
// this just checks that the query parser detects that we are explicitly inserting a composite id
Session s = openSession();
s.beginTransaction();
// intentionally reversing the order of the composite id properties to make sure that is supported too
s.createQuery( "insert into CompositeIdEntity (key2, someProperty, key1) select a.key2, 'COPY', a.key1 from CompositeIdEntity a" ).executeUpdate();
s.createQuery( "delete from CompositeIdEntity" ).executeUpdate();
s.getTransaction().commit();
s.close();
}
@Test
public void testInsertWithSelectListUsingJoins() {
// this is just checking parsing and syntax...

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.test.hql">
<class name="CompositeIdEntity">
<composite-id>
<key-property name="key1" />
<key-property name="key2" />
</composite-id>
<property name="someProperty" />
</class>
</hibernate-mapping>

View File

@ -0,0 +1,60 @@
package org.hibernate.test.hql;
import java.io.Serializable;
public class CompositeIdEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Long key1;
private String key2;
private String someProperty;
public Long getKey1() {
return key1;
}
public void setKey1( Long key1 ) {
this.key1 = key1;
}
public String getKey2() {
return key2;
}
public void setKey2( String key2 ) {
this.key2 = key2;
}
public String getSomeProperty() {
return someProperty;
}
public void setSomeProperty( String someProperty ) {
this.someProperty = someProperty;
}
@Override
public int hashCode() {
// not really needed, thus the dumb implementation.
return 42;
}
@Override
public boolean equals( Object obj ) {
if (this == obj) {
return true;
}
if ( !( obj instanceof CompositeIdEntity ) ) {
return false;
}
CompositeIdEntity other = ( CompositeIdEntity ) obj;
if ( key1 == null ? other.key1 != null : !key1.equals( other.key1 ) ) {
return false;
}
if ( key2 == null ? other.key2 != null : !key2.equals( other.key2 ) ) {
return false;
}
return true;
}
}