-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: hbm2ddl generates both unique and primary key (Oracle!)
PostPosted: Wed Feb 07, 2007 9:20 am 
Newbie

Joined: Mon Jan 15, 2007 11:45 pm
Posts: 1
AS 4.0.5.GA
Seam 1.1.5.GA
Oracle 9i

While trying to build and run the Seam Blog example, I stumbled across this hibernate-generated ddl, which is illegal in Oracle:

create table HitCount (
blog_name varchar2(255 char) not null,
pageviews number(10,0) not null,
primary key (blog_name),
<------- Oracle objects to
unique (blog_name)
<------- this
)

For a while, I thought it was a bug in hibernate-tools, but after referring to my copy of GK’s epic Java Persistence with Hibernate, I now think it is due to improper use of JPA annotations…

There are 3 java classes that define entities: Blog, BlogEntry and HitCount.

The author intended that there should be a one-to-one relationship between Blog and HitCount. So in Blog.java, you see:

@Entity
public class Blog {

/** the name of the blog */
@Id @Length(max=70)
private String name;



@OneToOne(optional=false, mappedBy="blog")
private HitCount hitCount;


The @OneToOne clause says that the relationship with HitCount must be bi-directional. So hbm2ddl will generate a foreign key column in the HitCount table. That column’s name will be a concatenation of the mappedBy attribute value (“blog”) plus an underscore plus the Blog table’s primary key column name (“name”); i.e. a foreign key column named “blog_name ” gets generated.

Also, since it is a one-to-one relationship, hbm2ddl also generates a unique constraint for that foreign key column as well.

Now look at HitCount.java, and see that the primary key column is also explicitely named “blog_name”. This is why the CREATE statement (above) for HitCount ends up with both unqiue and primary key of the same name.

@Entity
public class HitCount
{
@Id
@Column(name="blog_name")
private String blogName;


}

First point: should hbm2ddl be aware of this conflict ? Perhaps it doesn’t matter to other DBs such as hqsl.

Second point: Gavin expliciely advises us to not use ‘natural’ keys as primary keys. Section 4.2.3 of his book explains this (hope I don’t get in trouble for showing this extract!):

…Experience has shown that natural keys almost always cause problems in the
long run. A good primary key must be unique, constant, and required (never null
or unknown). Few entity attributes satisfy these requirements, and some that do
can’t be efficiently indexed by SQL databases (although this is an implementation
detail and shouldn’t be the primary motivation for or against a particular key). In
addition, you should make certain that a candidate key definition can never
change throughout the lifetime of the database before making it a primary key.
Changing the value (or even definition) of a primary key, and all foreign keys that
refer to it, is a frustrating task. Furthermore, natural candidate keys can often be
found only by combining several columns in a composite natural key. These composite
keys, although certainly appropriate for some relations (like a link table in
a many-to-many relationship), usually make maintenance, ad-hoc queries, and
schema evolution much more difficult.
For these reasons, we strongly recommend that you consider synthetic identifiers,
also called surrogate keys. Surrogate keys have no business meaning—they’re
unique values generated by the database or application…


If Gavins advice had been taken, this forum posting wouldn’t have been necessary.

Hope my analysis is correct and understandable.

Ian
Sydney


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.