12 Replies Latest reply on Mar 11, 2009 6:04 AM by wolfgangknauf

    @embedable annotation

    kkangsar

      Hi expert,

      I am thinking of creating a common Address.class which can be embedded into my customer and vendor class.

      My concern is, if I do so, what will be the end result when hibernate create a schema for my customer and vendor table?

      Will it create an address object in the database?

      Is this a good practice to create a common attribute for an entity and extend or embed to it? please advice.

      Thanks.

        • 1. Re: @embedable annotation
          itsme

          Per default hibernate creates your tables with all the fields of address as columns in that tables. So address is only a subset of columns of the table vendor or customer.

          • 2. Re: @embedable annotation
            kkangsar

            Do you mean my customer and vendor table will contain all the address column?

            • 3. Re: @embedable annotation
              itsme

              Yes. This is - especially for addresses - the common case, so there is no need to travers a relationship between tables.

              If you want to reuse your address entity, so there will be a address table, you can create a simple wrapper for your address with nothing more than an identifier and an embedded field address or your address must be a full entity and not an embeddable.

              • 4. Re: @embedable annotation
                kkangsar

                "If you want to reuse your address entity, so there will be a address table, you can create a simple wrapper for your address with nothing more than an identifier and an embedded field address or your address must be a full entity and not an embeddable."

                Would you mind to provide me the sample code for the above? thanks in advanced.

                • 5. Re: @embedable annotation
                  kkangsar

                  This is what i did

                  @Embeddable
                  public class Address implements Serializable{
                  private static final long serialVersionUID = 1L;
                  private String addr1;
                  private String addr2;
                  private String addr3;

                  @Column(name="ADDR1", length=30)
                  public String getAddr1() {
                  return addr1;
                  }
                  public void setAddr1(String addr1) {
                  this.addr1 = addr1;
                  }
                  @Column(name="ADDR2", length=30)
                  public String getAddr2() {
                  return addr2;
                  }
                  public void setAddr2(String addr2) {
                  this.addr2 = addr2;
                  }
                  @Column(name="ADDR3", length=30)
                  public String getAddr3() {
                  return addr3;
                  }
                  public void setAddr3(String addr3) {
                  this.addr3 = addr3;
                  }
                  }

                  @Entity
                  public class Customer implements java.io.Serializable {
                  private static final long serialVersionUID = 1L;
                  private String Id;
                  private String custName;

                  @Id
                  public String getId() {
                  return id;
                  }
                  public void setId(String id) {
                  this.id = id;
                  }
                  public String getCustName() {
                  return custName;
                  }
                  public void setCustName(String custName) {
                  this.custName = custName;
                  }
                  }

                  I dont know how to embed the address into customer.class. Can you please give some help. Thanks

                  • 6. Re: @embedable annotation
                    itsme

                    For the first one (use of @Embaddable and @Embedded) Customer class must be changed to:

                    @Entity
                    public class Customer implements Serializable {
                     // ... your member fields
                     private Address address;
                     // ... your set-/get-Methods
                     @Embedded
                     public Address getAddress() {
                     return address;
                     }
                     // ... setter as well
                    }
                    


                    For the second one (keeping @Embeddable and building a wrapper):
                    @Entity
                    public class AddressWrapper implements Serializable {
                    
                     @Id
                     private String id;
                    
                     @Embedded
                     private Address address;
                    
                     // getter and setter
                    }
                    

                    In this case your Customer class must be changed like
                    @Entity
                    public class Customer implements Serializable {
                     // ... your member fields
                     private AddressWrapper address;
                     // ... your set-/get-Methods
                     @OneToOne
                     public AddressWrapper getAddress() {
                     return address;
                     }
                     // ... setter as well
                    }
                    

                    For the last one you must change the annotation of Address to @Entity and change your Customer class like the above (without Wrapper).

                    • 7. Re: @embedable annotation
                      kkangsar

                      I got it. many thanks.

                      • 8. Re: @embedable annotation
                        wolfgangknauf

                        Hi,

                        though you already solved the problem, here is another idea: you could also use Inheritance strategies.

                        Declare your Address entity this way:

                        @Entity
                        @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
                        public abstract class Adress implements Serializable
                        {
                        

                        Let Person and Customer inherit from them:
                        @Entity
                        @DiscriminatorValue(value="person")
                        public class Person extends Address
                        {


                        Best regards

                        Wolfgang

                        • 9. Re: @embedable annotation
                          kkangsar

                          Hi Wolfgang,

                          Thanks for provided another solution. But I have the following question.

                          1. Do we need to specify the @@DiscriminatorColumn in the Address class, if yes, which column to specify?

                          2. What is the advantage by using @Inheritance over @Embedded? and when to use each of the method.

                          • 10. Re: @embedable annotation
                            kkangsar

                            My understanding of using inheritance SINGLE TABLE method is when the object is polymorphism, it means the single object can be describes multiple possible states.

                            For example: Account object, we may have SavingAccount and CheckingAccount, SavingAccount and CheckingAccount share some common attribute and have their own specific attribute. For this kind of object, we may use inheritance SINGLE TABLE method.

                            But in my case, Address.class, will it the right way to use this method? Please advise. Thanks.

                            • 11. Re: @embedable annotation
                              itsme

                              This is only a decision of the architecture of your object (and following up the database) model.

                              We use address only as tight as possible with the persons we track. So the address is not useful anymore when the person is gone. To avoid keeping orphans in the database we inlined address fields by using @Embeddable.

                              • 12. Re: @embedable annotation
                                wolfgangknauf

                                Hi kkangsar,

                                1) the DiscriminatorColumn name defaults to "DTYPE", so you need to specify the name only if you don't like the default ;-).

                                2) I don't have a simple answer this question ;-). Performance should not be an issue, because both approaches add the columns to the database table of the entity, so there are no additional entities. The approach with the @OneToOne relation ship (suggested by itsme) would result in an additional table.
                                The benefit of the inheritance approach is that you don't need to add properties (access to your embedded object) to the subclass. So it saves you some lines of code ;-).

                                Hope this helps

                                Wolfgang