开发者

Hibernate many-to-many relationship using non-identifier attribute for join column

Is it possible to create a many-to-many relationship in Hibernate using annotations if one of the join columns is not the identifier attribute for that entity? The parent entity has two different unique attributes, and I would like to be able to use either one as the join column, but I'm afraid Hibernate may not allow this.

In MySQL this is akin to creating a foreign key constraint that references a unique column on the parent table, but not the primary key.

In my MySQL database I have a join table with two different foreign key relationships to one of the parent tables. This was done to support two sets of code with the same database table, and I am trying to update the old object to use the new mappings so I can drop support for one of the foreign keys in the join table.

I read through the documentation and couldn't find anything explicit about whether this is supported or not. Any insight would be greatly appreciated.

Thanks!

Here are the Java classes (simplified for this question so please excuse any typos):

@Entity
@Table(name="TAG")
@org.hibernate.annotations.Table(appliesTo = "TAG")
public class Tag implements Externalizable {
    private Long id;
    private String name;

    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "TAG_ID", unique = true)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Id
    @Column(name = "NAME", unique = true)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        name = name.toLowerCase();
        this.name = name;
    }

}


@Entity
@Table(name="ITEM")
@org.hibernate.annotations.Table(appliesTo = "ITEM")
public class Item implements Externalizable {
    private Long id;
    private String name;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ITEM_ID")
    public Long getId() {
        return id;
    }

    public开发者_高级运维 void setId(Long id) {
        this.id = id;
    }

    @Column(name = "NAME")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        name = name.toLowerCase();
        this.name = name;
    }

    //tag support
    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @Fetch(value = FetchMode.SELECT)
    @JoinTable(name = "ITEM_TAG", joinColumns = {@JoinColumn(name = "ITEM_ID")}, inverseJoinColumns = @JoinColumn(name = "TAG_NAME", referencedColumnName="NAME"))
    @OrderBy("name")
    public Set<Tag> getTags() {
        return tags;
    }

    public void setTags(Set<Tag> tags) {
        this.tags = tags;
    }
}

Here are the MySQL table definitions (simplified for this question):

mysql> desc tag;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| tag_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name   | varchar(255)     | NO   | UNI | NULL    |                |
+--------+------------------+------+-----+---------+----------------+

mysql> desc item;
+---------+------------------+------+-----+---------+----------------+
| Field   | Type             | Null | Key | Default | Extra          |
+---------+------------------+------+-----+---------+----------------+
| item_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name    | varchar(255)     | NO   |     | NULL    |                |
+---------+------------------+------+-----+---------+----------------+

mysql> desc item_tag;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| item_tag_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| item_id     | int(10) unsigned | NO   | MUL | NULL    |                |
| tag_id      | int(10) unsigned | NO   | MUL | NULL    |                |
| tag_name    | varchar(255)     | NO   | MUL | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+


You can do this, but you'll need to set the relationship as read only, as hibernate is not that intelligent to know how to populate the table item_tag.

I don't think your current mapping will work because you have a cascade all in Item. If you need more information, give me a shout and I can try to put together a sample mapping

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜