Multiple join associations in hibernate
My question is related to database design and also how to model that design in Hibernate. I have two tables with the following primary keys:
BLOCK (BLOCK_ID)
BLOCK_SHP (BLOCK_ID, SHAPE_VERSION)
BLOCK to BLOCK_SHP is a one-to-many relationship as a single block can have many different versioned shapes associated with it. So far so good.
The second association is that I also want to be able to get the current shape for the Block. To do this, I have added another attribute to the BLOCK table:
CUR_SHAPE_VERSION
BLOCK_ID and CUR_SHAPE_VERSION now form a foreign key to the BLOCK_SHP table on BLOCK_ID, SHAPE_VERSION. Each block may have 0 or 1 current shapes.
In Hibernate, I have set this second association up in the following way:
@OneToOne( cascade = CascadeType.ALL, optional = true ) @NotFound( action = NotFoundAction.IGNORE ) @JoinColumns( { @JoinColumn( name = "BLOCK_ID", referencedColumnName = "BLOCK_ID", insertable = false, updatable = false ), @JoinColumn( name = "CUR_SHAPE_VERSION", referencedColumnName = "SHAPE_VERSION", insertable = false, updatable = false ) } ) public BlockShape getCurrentShape() { return currentShape; }
The @NotFound annotation was required because Hibernate was having trouble dealing with nullable one-to-one associations. 开发者_开发问答If it doesn't find the association it ignores it instead of throwing an error.
This isn't very satisfying to me though, because it means that Hibernate isn't really aware of the proper relationship between the entities. For example, if I query for currentShape is not null, Hibernate does not know how to perform this query properly - it is querying on block_id is not null or cur_shape_version is not null.
So I guess I have a few questions. First, is there a better way to model this second association in the database? Second, is there a better way in Hibernate to set up the annotations for it to better understand the relationship and be able to properly query on the shape table?
Thanks for any help.
The easiest way is to use a surrogate primary key for the Shape entity. The tables would look like this:
BLOCK (BLOCK_ID primary key, CURRENT_SHAPE_ID foreign key references SHAPE.SHAPE_ID)
SHAPE (SHAPE_ID primary key, SHAPE_VERSION, BLOCK_ID foreign key references BLOCK.BLOCK_ID)
The use of composite keys is discouraged by Hibernate, for good reasons (and the problem you're having is just one of them).
精彩评论