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

    UniqueConstraint as primary key?

    Jens Elkner Apprentice

      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?
          Emmanuel Bernard Master

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

          • 2. Re: UniqueConstraint as primary key?
            Jens Elkner Apprentice

             

            "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?
              Emmanuel Bernard Master

              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?
                Jens Elkner Apprentice

                 

                "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?
                  Emmanuel Bernard Master

                  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?
                    Jens Elkner Apprentice

                     

                    "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?
                      Emmanuel Bernard Master

                       

                       @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?
                        Jens Elkner Apprentice

                         

                        "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?
                          Emmanuel Bernard Master

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

                          • 10. Re: UniqueConstraint as primary key?
                            Jens Elkner Apprentice

                             

                            "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?
                              Emmanuel Bernard Master

                              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.