Search code examples
javahibernatejpacomposite-key

hibernate MappingException: Could not determine type using composite key


(Using Spring 3.1 and hibernate 3.3)

I am using an IdClass with an entity that maps to a table that has 3 columns as a composite key.

My tests are failing throwing a runtime exception MappingException complaining that hibernate cannot determine the type for one of my columns used as part for the composite key. in this case it is the set column (aka in the db table as "set_id").

Here is a cut down version of my entity

@Entity
@Table(name = "the_table")
@IdClass(CompositeKey.class)
public class MyEntity {

    @Id
    @Column(name = "page_id")
    private Integer pageId;

    @Id
    @Column(name = "xml_id")
    private Integer xmlId;

    @Id
    @ManyToOne
    @JoinColumn(name = "set_id")
    private CustomSet set;


    public CustomSet getSet() {
        return set;
    }

    public void setSet(CustomSet set) {
        this.set = set;
    }

    public Integer getPageId() {
        return pageId;
    }

    public void setPageId(Integer pageId) {
        this.pageId = pageId;
    }

    public Integer getXmlId() {
        return xmlId;
    }

    public void setXmlId(Integer xmlId) {
        this.xmlId = xmlId;
    }
}

Here is the composite key id class

public class CompositeKey implements Serializable {

    private Integer pageId;

    private Integer xmlId;

    private CustomSet set;

    public CompositeKey(){}

    public CompositeKey(Integer pageId, Integer xmlId, CustomSet set){
        this.pageId = pageId;
        this.xmlId = xmlId;
        this.set = set;
    }

    public Integer getPageId() {
        return pageId;
    }

    public Integer getXmlId() {
        return xmlId;
    }


    public CustomSet getSet() {
        return set;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof CompositeKey)) return false;

        CompositeKey that = (CompositeKey) o;

        if (!getPageId().equals(that.getPageId())) return false;
        if (!getXmlId().equals(that.getXmlId())) return false;
        return getSet().equals(that.getSet());

    }

    @Override
    public int hashCode() {
        int result = getPageId().hashCode();
        result = 31 * result + getXmlId().hashCode();
        result = 31 * result + getSet().hashCode();
        return result;
    }
}

Solution

  • I found that the answer was simple enough, I needed to annotate the "set" column in the composite key class with the same mapping type as in the entity.

    Also because I have table column names that are different in to the variable names in the code, I had to add the extra column annotations to the variables in the composite key class as well.

    here is the code change I made to the CompositeKey...

    @Column(name = "page_id")
    private Integer pageId;
    
    @Column(name = "xml_id")
    private Integer xmlId;
    
    @ManyToOne
    @JoinColumn(name = "set_id")
    private CustomSet set;
    

    That's it, now hibernate knows what type of mapping and column names to use with that database table. I had assumed it would pick that all up from the entity, but I guess not.