Kimope
Kimope

Reputation: 13

Composite primary keys in Hibernate with annotations

I´m trying to do the following relations using Hibernate + annotations:

Relation

However, I get this error:

"A foreign key referring *.street from *.house has the wrong number of column: should be 2".

Here is my code:

House

@Entity
@Table(name = "HOUSE")
@GenericGenerator(name = "pkgenerator", strategy = "increment")
public class House extends Entity {
private static final long serialVersionUID = 1L;

private Integer codHouse;
private Group codGroup;
private Street codStreet;

@Transient
public Integer getPrimaryKey() {
    return codHouse;
}
@Transient
public void setPrimaryKey(Integer primaryKey) {
    setCodHouse(primaryKey);
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "pkgenerator")
@Column(name="CODHOUSE", nullable=false, length=9)
public Integer getCodHouse() {
    return codHouse;
}
public void setCodHouse(Integer codHouse) {
    this.codHouse = codHouse;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn (name="CODGROUP", nullable=false)
public Group getCodGroup() {
    return codGroup;
}
public void setCodGroup(Group codGroup) {
    this.codGroup = codGroup;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn (name="CODSTREET", nullable=false)
public Street getStreet() {
    return codStreet;
}
public void setStreet(Street codStreet) {
    this.codStreet = codStreet;
}

Street

@Entity
@Table(name = "STREET")
@GenericGenerator(name = "pkgenerator", strategy = "increment")
@AssociationOverrides({
    @AssociationOverride(name = "primaryKey.codGroup", 
        joinColumns = @JoinColumn(name = "CODGROUP")),
    @AssociationOverride(name = "primaryKey.codStreet",
        joinColumns = @JoinColumn(name = "CODSTREET"))
})
public class Street extends Entity implements Serializable{

    private static final long serialVersionUID = 1L;

    private StreetPK primaryKey;
    private String name;

    @EmbeddedId
    public StreetPK getPrimaryKey() {
        return primaryKey;
    }
    public void setPrimaryKey(StreetPK primaryKey) {
        this.primaryKey = primaryKey;
    }

    @Column(name = "NAME", nullable = true, length = 30)
    public String getName() {
        return name;
    }
    public void setName(String nname) {
        this.name = name;
    }
}

StreetPK

@Embeddable
public class StreetPK implements Serializable {

    private static final long serialVersionUID = 1L;

    private Group codGroup;
    private Integer codStreet;

    public StreetPK() {}

    public StreetPK(Group codGroup, Integer codStreet){
        this.codGroup = codGroup;
        this.codStreet = codStreet;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="CODGROUP", nullable=false)
    public Group getCodGroup() {
        return codGroup;
    }
    public void setCodGroup(Group codGroup) {
        this.codGroup = codGroup;
    }

    @JoinColumn(name="CODSTREET", nullable=false)
    public Integer getCodStreet() {
        return codStreet;
    }

    public void setCodStreet(Integer codStreet) {
        this.codStreet = codStreet;
    }
}

Group

@Entity
@Table(name = "GROUP")
public class Group extends Entity implements Serializable{

    private static final long serialVersionUID = 1L;

    private Integer codGroup;

    @Transient
    public Integer getPrimaryKey() {
        return codGroup;
    }
    @Transient
    public void setPrimaryKey(Integer primaryKey) {
        setCodGroup(primaryKey);
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "pkgenerator")
    @Column(name="CODGROUP", nullable=false, length=9)
    public Integer getCodGroup() {
        return codGroup;
    }
    public void setCodGroup(Integer codGroup) {
        this.codGroup = codGroup;
    }
}

The problem is in StreetPK, if I don´t include codGroup here the error disappears. Thanks in advance.

Upvotes: 1

Views: 584

Answers (1)

JMSilla
JMSilla

Reputation: 1449

When annotating the getStreet() getter, you need to put @JoinColumns annotation with two @JoinColumn annotations inside specifying the two columns that compound the Street key:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns ({
    @JoinColumn(name = "CODSTREET", referencedColumnName = "CODSTREET", nullable = false),
    @JoinColumn(name = "CODGROUP", referencedColumnName = "CODGROUP", nullable = false)
})
public Street getStreet() { ... }

Upvotes: 1

Related Questions