14

I want do a one-to-many relationship between two tables using a join table.

This is why I want to use a join table:

Finally, I want to use Hibernate annotations to perform this.

I found some examples to do this using xml mapping but nothing with annotations.

I believe this would be how the tables need to be created

CREATE TABLE `PRODUCT` (
  `PRODUCT_ID`      BIGINT       PRIMARY KEY AUTO_INCREMENT
);

CREATE TABLE `PARTS` (
  `PART_ID`         BIGINT       PRIMARY KEY AUTO_INCREMENT
);

-- USER_IMAGE_ID must be unique if we want a one-to-many relationship between PRODUCTS & PARTS tables
CREATE TABLE `USER_DETAILS_IMAGE` (
  `PRODUCT_ID`      BIGINT,
  `PART_ID`         BIGINT UNIQUE,
  CONSTRAINT `FK_PRODUCT_ID`  FOREIGN KEY (`PRODUCT_ID`)   REFERENCES `PRODUCT`(`PRODUCT_ID`),
  CONSTRAINT `FK_PART_ID`     FOREIGN KEY (`PART_ID`)      REFERENCES `PARTS`(`PART_ID`)
);
Community
  • 1
  • 1
Adriano
  • 19,463
  • 19
  • 103
  • 140

1 Answers1

44

Don't look for examples. Read the official documentation:

@Entity
public class Product {

    private String serialNumber;
    private Set<Part> parts = new HashSet<Part>();

    @Id
    public String getSerialNumber() { return serialNumber; }
    void setSerialNumber(String sn) { serialNumber = sn; }

    @OneToMany
    @JoinTable(
            name="PRODUCT_PARTS",
            joinColumns = @JoinColumn( name="PRODUCT_ID"),
            inverseJoinColumns = @JoinColumn( name="PART_ID")
    )
    public Set<Part> getParts() { return parts; }
    void setParts(Set parts) { this.parts = parts; }
}


@Entity
public class Part {
   ...
}

Also, note that this is the default for unidirectional one-to-many associations. So you don't even have to provide the @JoinTable annotation if the default table and column names suit you.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • thank you JB Nizet. I have updated my question with what I believe the tables required would look like. Is that correct? – Adriano Oct 24 '12 at 11:37
  • thanks for pointing the documentation (the single page version is handy!). I do find docs precise but unfriendly that's why I always look for examples when starting to work on new techs. That one was kind of nice but missed the table creation part too http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html – Adriano Oct 24 '12 at 11:40
  • That looks right, except SERIAL_NUMBER should be PRODUCT_ID to match the annotations. – JB Nizet Oct 24 '12 at 11:55
  • I see, so serialNumber is matched to PRODUCT_ID since it is mentioned in the @JoinTable part I assume. I edited my question with the relevant changes. – Adriano Oct 24 '12 at 12:06
  • Just in case any of you see this. Say I wanted the Part class to have a Product field that referenced the parent how would I achieve that? – Link19 Feb 09 '15 at 10:41
  • @JBNizet I am trying exactly similar approach and I am seeing Join query in SQL logs going. But, in the parent entity, the child is not getting set. i.e If we consider `parts` as child, its a persistent bag with 0 entry. What can be the issue? Note: I am using List, instead of Set, that should not be the issue I suppose. And also, I am fetching multiple `Product.` (List of products) So, I am expecting that inside List of Product, i should be able to find List of parts – Vivek Vardhan Jan 02 '20 at 08:42
  • 1
    @VivekVardhan if you have a question, then ask a question. With the relevant code, explanations, test case reproducing the issue, etc. – JB Nizet Jan 02 '20 at 08:44