letthefireflieslive
letthefireflieslive

Reputation: 12664

How to generate an id for an embeddable class?

One Note : Many Files

How can I assign an id in File since I cannot annotate it with @Id while keeping it embeddable? Currently, id in File table is null.

Note

@Entity
public class Note {
    @Id
    @GeneratedValue
    @JsonProperty(value = "noteID", access = Access.READ_ONLY)
    private Long id;

    @ElementCollection
    @CollectionTable(
          name = "FILE",
          joinColumns = @JoinColumn(name = "NOTE_ID")
    )
    List<File> files;

}

File

@Embeddable
public class File {
    private Long id;

    private String name;

    private String contentType;

    private String uri;
}

Upvotes: 0

Views: 3473

Answers (3)

Salil Joshi
Salil Joshi

Reputation: 33

You can use the @CollectionId annotation in the org.hibernate.annotations package. Since you cannot make this an Entity as per your answers above, you can make use of the @CollectionId annotation. This annotation need 3 properties: the columns, the generator and a type for the primary key in your Collection Object. Below is an example to help you :-

import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;

 import javax.persistence.AttributeOverride;
 import javax.persistence.AttributeOverrides;
 import javax.persistence.Embedded;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.Lob;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;

 import org.hibernate.annotations.CollectionId;
 import org.hibernate.annotations.GenericGenerator;
 import org.hibernate.annotations.Type;

 import javax.persistence.Column;
 import javax.persistence.ElementCollection;


 @Entity
 @Table(name="USER_DETAILS")
 public class UserDetails 
 {

   private int userId;

   private String  userName;
   private Date joinedDate;
   private String description;

   private Collection<Address> listOfAddresses=new ArrayList<Address>();
   @Id@GeneratedValue(strategy=GenerationType.SEQUENCE)
   public int getUserId() 
   {
    return userId;
   }
   public void setUserId(int userId) 
   {
    this.userId = userId;
   }
   public String getUserName() 
   {
    return userName;
   }
   public void setUserName(String userName) 
   {
    this.userName = userName;
   }
   @Temporal(TemporalType.DATE)
   public Date getJoinedDate() 
   {
    return joinedDate;
   }
   public void setJoinedDate(Date joinedDate) 
   {
    this.joinedDate = joinedDate;
   }
   @Lob
   public String getDescription() 
   {
    return description;
   }
   public void setDescription(String description) 
   {
    this.description = description;
   }
   public String toString()
   {
      return "[ "+getUserId()+", "+getUserName()+", "+", "+getJoinedDate()+", "+getDescription()+" ]";
   }
   @ElementCollection  
   @JoinTable(name="User_Address", joinColumns=@JoinColumn(name="User_Id"))
   @GenericGenerator(name="increment-gen",strategy="increment")
   @CollectionId(columns= {@Column(name="ADDRESS_ID")}, generator="increment-gen", type=@Type(type="long"))
   public Collection<Address> getListOfAddresses() {
    return listOfAddresses;
   }
   public void setListOfAddresses(Collection<Address> listOfAddresses) {
    this.listOfAddresses = listOfAddresses;
   }
 }

See the getter of the Collection, I have put in the annotation @CollectionId and have also specified the @GenericGenerator which is from the same package and provides a strategy for generating the Primary Key in your collection. I have used the same Generator in my @CollectionId. Hope this helps.

Upvotes: 0

Radhakrishna Pemmasani
Radhakrishna Pemmasani

Reputation: 766

Use @Embeddableonly when you need different objects but single entity. i.e 2 different classes together making a single database table.

Upvotes: 0

Jens Schauder
Jens Schauder

Reputation: 81862

Just make it a proper entity. @Embeddable is useful for value objects, i.e. objects that are identified by their values. But since you need an id this is obviously not the case in your scenario.

Your reason

as per our requirement, file only exist within the note context

for choosing an embeddable is not valid. While I have seen phrases like this all over the place on the internet, you can use @Embeddables in what ever context you want. As @Embeddable your File instances are not bound more or less to your Note instances than as @Entity.

Upvotes: 1

Related Questions