I'm trying to convert part of a data-access 开发者_如何学JAVAlayer into hibernate and running into some trouble getting the collection association right. I am using hibernate annotations, and have two Entities that are related (the base configuration here is working, just not the join). Some names have been obfuscated:
Spring 3, Hibernate 3, Java 6, MySQL 5.
Container has a List of Videos. Both of these classes are mapped in hibernate with annotations.
Unfortunately, the mapping table has an unusual schema. It looks like this:
container_mapping:
+-----------------+------------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+-------------------+-------+
| internal_id | int(10) unsigned | NO | PRI | | |
| external_id | varchar(255) | NO | PRI | | |
| mapping_type_id | int(4) unsigned | NO | PRI | | |
| creation_date | timestamp | NO | | CURRENT_TIMESTAMP | |
+-----------------+------------------+------+-----+-------------------+-------+
internal_id maps to container.id and external_id maps to video.id when mapping_type_id = 2
The query to pull back by id:
select * from container c, container_mapping cm, video v where cm.mapping_type_id=2 and c.episode_id = cm.internal_id and cm.external_id = v.id and c.episode_id=?;
I can't seem to find a good example to having a collection join WITH a join field having a specific value. At this point I'm grasping at straws. The (incomplete) version is here:
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinTable(name="container_mapping",
joinColumns = @JoinColumn(name="external_id"))
private List<Video> videos = Lists.newArrayList();
Anyone have any pointers on how to proceed?
You could try mapping the videos collection this way:
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinTable(name="container_mapping",
joinColumns = @JoinColumn(name="internal_id"),
inverseJoinColumns = @JoinColumn(name="external_id")
@WhereJoinTable(clause="mapping_type_id=2")
private List<Video> videos = Lists.newArrayList();
The idea behind this mapping is following:
- The joinColumns parameter of the @JoinTable annotation is used to configure the column, which stores the value of container id.
- The column storing the video id is configured by using the inverseJoinColumns parameter of the @JoinTable annotation.
- The @WhereJoinTable annotation can be used to restrict the rows selected from the join table. The clause parameter must be written by using SQL. In this case it used to restrict the value of mapping_type_id, which must be 2.
精彩评论