When trying to use an entity with a composite primary key where the Java bean field name is not identical with the column name in the database, a Hibernate exception is thrown because the generated query will look for the field name rather than the column name.
Example:
The entity MyEntity uses the composite primary key
String firstName
String lastName
while the columns in the database are called
first_name
last_name
The generated code will look for firstName = "whatever" instead of first_name = "whatever" which causes the problem.
I was able to track the issue down to the template
EntityPK.vsl
where the simple answer is to move the annotations in that template from fields to properties and all will be fine. I don't have a patch right now, but this means basically to change lines 38-42 from current CVS from:
#foreach ($field in $entity.Fields)
39 #if ($field.isPrimaryKey())
40 @javax.persistence.Column(name="${field.ColumnName}")
41 public $field.Type ${field.Name};
42 #end
to
#foreach ($field in $entity.Fields)
39 #if ($field.isPrimaryKey())
41 public $field.Type ${field.Name};
42 #end
(remove line 40)
and lines 61-66 from
61 #foreach ($field in $entity.Fields)
62 #if ($field.isPrimaryKey())
63 public $field.Type get${field.Name.Sentensized}()
64 {
65 return ${field.Name};
66 }
to
61 #foreach ($field in $entity.Fields)
62 #if ($field.isPrimaryKey())
40 @javax.persistence.Column(name="${field.ColumnName}")
63 public $field.Type get${field.Name.Sentensized}()
64 {
65 return ${field.Name};
66 }
(re-inserting that old line 40 between 62 and 63.)
Supporting information:
http://www.hibernate.org/hib_docs/annotations/reference/en/html/entity.html#entity-mapping
Section 2.2.1
Depending on whether you annotate fields or methods, the access type used by Hibernate will be field or property. The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access. Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type from the position of @Id or @EmbeddedId.
---
As for the entity class, the properties (and not the fields) are annotated, this seems to be inherited for the embedded PK class, thus ignoring the field mapping on the fields rather than the properties.
At least the above change is a "works for me" and minimal invasive.