Skip to content

Commit

Permalink
HHH-3434 - hql insert doesn't work when inserting into a table with c…
Browse files Browse the repository at this point in the history
…omposite-id
  • Loading branch information
Andrei Badea authored and stliu committed Oct 21, 2011
1 parent fcc80c8 commit da540c7
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 5 deletions.
Expand Up @@ -24,12 +24,15 @@
*/
package org.hibernate.hql.ast.tree;

import java.sql.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.sql.Types;
import java.util.Set;

import org.hibernate.QueryException;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.type.ComponentType;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;

Expand All @@ -51,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() ) {
Expand Down Expand Up @@ -167,9 +172,26 @@ private void visitPropertySpecNodes(AST propertyNode, List types) {
throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" );
}

if ( name.equals( persister.getIdentifierPropertyName() ) ) {
explicitIdInsertion = true;
}
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() ] ) ) {
Expand Down
Expand Up @@ -50,7 +50,8 @@ public String[] getMappings() {
"legacy/Multi.hbm.xml",
"hql/EntityWithCrazyCompositeKey.hbm.xml",
"hql/SimpleEntityWithAssociation.hbm.xml",
"hql/BooleanLiteralEntity.hbm.xml"
"hql/BooleanLiteralEntity.hbm.xml",
"hql/CompositeIdEntity.hbm.xml"
};
}

Expand Down Expand Up @@ -465,6 +466,17 @@ public void testInsertWithGeneratedTimestampVersion() {
s.close();
}

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

public void testInsertWithSelectListUsingJoins() {
// this is just checking parsing and syntax...
Session s = openSession();
Expand Down
@@ -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>
@@ -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;
}
}

0 comments on commit da540c7

Please sign in to comment.