2

I am using JPA with Hibernate 4.x., and postgresql 9.x, but I wonder some problem.

When using @ElementCollection annotation, and I configured Set type embedded field, I expect to generate Primary key of embeddable Collection Table, but it's not working. I can find just one foreign key against owner of relationship. i wonder why do not it generate primary key. This is my test code. A.java

@Entity
public class A {
    @Id
    private Long id;
    @Column(name = "\"as\"")
    private String as;
    public String getAs() {
        return as;
    }

    public void setAs(String as) {
        this.as = as;
    }

    @ElementCollection
    private Set<B> bs = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<B> getBs() {
        return bs;
    }

    public void setBs(Set<B> bs) {
        this.bs = bs;
    }
}

B.java

@Embeddable
public class B {
    private String col1;
    private String col2;

    public String getCol1() {
        return col1;
    }

    public void setCol1(String col1) {
        this.col1 = col1;
    }

    public String getCol2() {
        return col2;
    }

    public void setCol2(String col2) {
        this.col2 = col2;
    }
}

the result is

Hibernate: 
    create table A (
        id int8 not null,
        "as" varchar(255),
        primary key (id)
    )
Hibernate: 
    create table A_bs (
        A_id int8 not null,
        col1 varchar(255),
        col2 varchar(255)
    )
Hibernate: 
    alter table A_bs 
        add constraint FK_rcecll1ao3brmwwnsep3iqq3p 
        foreign key (A_id) 
        references A

Let me know why it did not generate primary key? Thanks in advance~

ohyun
  • 41
  • 1
  • 6

2 Answers2

1

Because @ElementCollection is used for mapping collections of simple elements, which is not the same as entities. The only thing they need is a reference to owning entity which is properly generated by Hibernate (column A_id and foreign key (A_id) references A). Take a look at this post for more information.

If you really need a primary key in the embeddable object, consider making it a proper entity.

Community
  • 1
  • 1
Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • yea i know what u mean. but i want to use ElementCollection for mapping collections of simple elements as that u said. As u saw that, class B is not entity, just simple type class attached embedded annotation. I wonder wheather it generates compound primary key(A_id, col1, col2) of A_bs collection table or not. I expected to generate primary key, but it wasn't. I want to know why. I could see generating primary key when using ElementCollection in several JPA books. – ohyun Apr 23 '15 at 00:30
  • I used java.util.Set type for class field attached `@ElementCollection` annotation. Then I expect to generate PK because they must to be unique. thanks – ohyun Apr 23 '15 at 00:43
  • In which JPA books did you see that? Did you read this? http://en.m.wikibooks.org/wiki/Java_Persistence/ElementCollection#Primary_keys_in_CollectionTable – Predrag Maric Apr 23 '15 at 05:13
  • No, The book I read is ProJPA 2nd edition. In Chap5, there is a example code having `@ElementCollection private Set nicknames`, and the author shows result ERD figure. The figure showed me EMPLOYEE_NICKNAMES table have compound primary key(employee_id, nicknames). Additionally, the book, Java persistence with Hibernate also have same contents as using Set Type fields. – ohyun Apr 23 '15 at 06:09
  • 1
    I think it's correct. If we use Set type field of basic type using `@ElementCollection` annotation, ORM need to make compound primary key(target entity fk + target's other columns) not to make duplicate rows in database. But, I could see not to make PK, just only FK of collection table by ORM frameworks. – ohyun Apr 23 '15 at 06:10
  • I saw what u linked. The sentence, "So, the JPA provider will most likely assume that the combination of all of the fields in the Embeddable are unique," means ORM framework don't make compound primary key automatically? If it's true, why do some books display compound primary key as using `@ElementCollection` annotation – ohyun Apr 23 '15 at 06:21
  • Yes, your understanding of that sentence is correct. I don't know why some books show examples of compound primary key, maybe some JPA providers do support it. I couldn't find anything in the JPA specification about weather ID in collection table is supported or not. – Predrag Maric Apr 23 '15 at 07:53
  • I can understand what I didn't know. I appreciate it. – ohyun Apr 23 '15 at 09:08
0

To generate a primary key for an embeddable collection like Set need to mark all columns of embeddable class with annotation @Column(nullable = false), due to requirement that nullable fields could not be a part of composite primary key

o_nvk
  • 56
  • 5