11 Replies Latest reply on May 3, 2005 3:48 AM by epbernard

    UniqueConstraint as primary key?

    elkner

      Are there any plans to implement, that UniqueConstraints can be used as primary key?

      Ok, at the moment one can use composite PKs via @Embeddable, however this is not sufficient, since @OneTo*|@ManyTo* can not be used in Embeddables :( (and a lot of legacy DBs use unique constraints as PK) ... And beside it would free us from writing a bunch of classes/code ... ;-)

        • 1. Re: UniqueConstraint as primary key?
          epbernard

          I don't see the relation between unique constrains and @Embedded limitations. Could you explicit your case?

          • 2. Re: UniqueConstraint as primary key?
            elkner

             

            "epbernard" wrote:
            I don't see the relation between unique constrains and @Embedded limitations. Could you explicit your case?


            Hmm, yes because its a little bit fuzzy IMHO. On one side, spec says, for composite PKs one has to use a class (2.1.4), on the other side it states, that @UniqueConstraint.primary says, whether the constraint is a primary key or not (5.1.4).

            If I understand 5.1.26 right, one is not allowed to apply @One* | @Many* to properties/fields of an @Embeddable. So to achieve cascading, one has to use a unique constraint with primary, to be able to cascade.

            E.g. here an extract from a legacy database:
            CREATE TABLE products (
             products_id int NOT NULL auto_increment,
             PRIMARY KEY (products_id),
             -- ..
             )
            
            CREATE TABLE products_description (
             products_id int NOT NULL auto_increment,
             language_id int NOT NULL default '1',
             products_name varchar(64) NOT NULL default '',
             -- ...
             PRIMARY KEY (products_id,language_id),
            )
            


            So we have a composite PK in products_description, which refers to the products_id in products (and beside this to a language_id in the language table). So if either the product or the language is deleted, the description should be thrown away, too ...



            • 3. Re: UniqueConstraint as primary key?
              epbernard

              We will support @ManyToOne inside components eventually (as a proprietary candy)
              What is working right now is using @ManyToOne in the entity with @JoinColumn(insertable=false, updatable=false)

              • 4. Re: UniqueConstraint as primary key?
                elkner

                 

                "epbernard" wrote:
                We will support @ManyToOne inside components eventually (as a proprietary candy)


                This would be nice :). But aren't there hibernate and jboss people in the spec team ? Isn't it possible to ask them for including it in the spec - I think, many people, which have to work with "old"/legacy DBs will need this (as long as unique.primary=true is not supported) and so should be standard ...

                "epbernard" wrote:
                What is working right now is using @ManyToOne in the entity with @JoinColumn(insertable=false, updatable=false)


                OK. But than (if hibernate needs to create/update the db), there is no PK (products_id,language_id) created (or did I get it wrong?).

                • 5. Re: UniqueConstraint as primary key?
                  epbernard

                  You still have to keep your usual class PK, using properties to bind to the same columns as the insertable / updatable = false binds.

                  @ManyToOne()
                  @JoinColumn(name="foo", insertable=false, updatable=false)


                  ...
                  in the PK class

                  @Column("foo")
                  public Integer getFooId()

                  • 6. Re: UniqueConstraint as primary key?
                    elkner

                     

                    "epbernard" wrote:
                    You still have to keep your usual class PK, using properties to bind to the same columns as the insertable / updatable = false binds


                    Hmmm, cascading wrt. to delete seems not to work. I tried:

                    @ManyToOne(cascade=CascadeType.ALL)
                     @JoinColumn(name="products_id", insertable=false, updatable=false)
                     @EmbeddedId({
                     @AttributeOverride(name="products_id"),
                     @AttributeOverride(name="language_id") })
                     public A_ProductDescriptionPK getPk() {
                     return this.pk;
                     }


                    I also tried to set the target entity as 'targetEntity="foo.bar.server.A_Product"' but seems to be ignored, i.e. the product description gets not removed, when the product is removed from the db.

                    Any hints?

                    • 7. Re: UniqueConstraint as primary key?
                      epbernard

                       

                       @EmbeddedId({
                       @AttributeOverride(name="products_id"),
                       @AttributeOverride(name="language_id") })
                       public A_ProductDescriptionPK getPk() {
                       return this.pk;
                       }
                      
                       @ManyToOne(cascade=CascadeType.ALL)
                       @JoinColumn(name="products_id", insertable=false, updatable=false)
                       public ProductDescription description {
                       }


                      • 8. Re: UniqueConstraint as primary key?
                        elkner

                         

                        "epbernard" wrote:
                         @EmbeddedId({
                         @AttributeOverride(name="products_id"),
                         @AttributeOverride(name="language_id") })
                         public A_ProductDescriptionPK getPk() {
                         return this.pk;
                         }
                        
                         @ManyToOne(cascade=CascadeType.ALL)
                         @JoinColumn(name="products_id", insertable=false, updatable=false)
                         public A_ProductDescription description {
                         }


                        Hmm, no FK to products.products_id is created on the products_description table (wondering, how hibernate should find that out) ... Same counts for
                        @ManyToOne(cascade=CascadeType.ALL)
                         @JoinColumn(name="products_id", insertable=false, updatable=false,
                         referencedColumnName="products_id")
                         public A_Product product() {
                         return null;
                         }


                        • 9. Re: UniqueConstraint as primary key?
                          epbernard

                          Hibernate does not need explicit FK in the DB. Feel free to add them to your DDL

                          • 10. Re: UniqueConstraint as primary key?
                            elkner

                             

                            "epbernard" wrote:
                            Hibernate does not need explicit FK in the DB. Feel free to add them to your DDL


                            Hmmm. But would be nice and AFAIK consistent wrt. Persistence API 2.1.8.3.2

                            • 11. Re: UniqueConstraint as primary key?
                              epbernard

                              I misunderstand you, forget my last post

                              public class A_ProductDescription
                               @EmbeddedId({
                               @AttributeOverride(name="products_id"),
                               @AttributeOverride(name="language_id") })
                               public A_ProductDescriptionPK getPk() {
                               return this.pk;
                               }
                               @ManyToOne(cascade=CascadeType.ALL)
                               @JoinColumn(name="products_id", insertable=false, updatable=false,
                               referencedColumnName="products_id")
                               public A_Product product() {
                               return null;
                               }

                              does create a product_id column witch from your application POV refers to Product_Description.
                              There is no *explicit* foreign key constraint, but nowhere in the spec, we mandate a foreign key constraint in your DB model.