Search code examples
javajpaentities

How to connect JPA entity classes? (one-to-many/many-to-one)


If have these two entities :

@Entity
@Table(name = "CUSTOMER")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "FIRST_NAME") //Attributes in the entitiy
    private String firstName;

    @Column(name = "LAST_NAME")
    private String lastName;

    @Column(name = "ADDRESS")
    private String address;

and

@Entity
@Table(name = "ADDRESS")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "STREET_NAME") //Attributes in the entitiy
    private String streetName;

    @Column(name = "HOUSE_NUMBER")
    private int houseNumber;

How do I now connect these two entities and define that Customer has many Addresses?


Solution

  • You can easily find tons of examples of this over Internet. I highly suggest to take a look at ObjectDB website.

    For this specific scenario, you can define them as below:

    @Entity
    @Table(name = "CUSTOMER")
    public class Customer {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @Column(name = "FIRST_NAME") //Attributes in the entity
        private String firstName;
    
        @Column(name = "LAST_NAME")
        private String lastName;
    
        @Column(name = "ADDRESS")
        private String address;
    
        @OneToMany(mappedBy = "customer")
        private List<Address> addresses;
    }
    

    and have a reference to your customer in Address class as:

    @Entity
    @Table(name = "ADDRESS")
    public class Address {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @Column(name = "STREET_NAME") //Attributes in the entitiy
        private String streetName;
    
        @Column(name = "HOUSE_NUMBER")
        private int houseNumber;
    
        @ManyToOne(fetch = FetchType.LAZY)
        private Customer customer;
    }
    

    EDIT: Based on your request to have an example for many to many relation, here is the way you can implement it for your Customer and Address entities:

    First you should have an intermediate table having two foreign keys, one referring to customer table and the other referring to address. Suppose you name this intermediate table customer_address, then it's data would be something like this:

    select * from customer_address;
    
    customer_id | address_id
    ------------------------
        12      |     15
        12      |     14
        12      |     13
        2       |     15
        2       |     13
        19      |     11
    

    Now you should update your annotations and tell JPA to use this table to infer the many to many relationship among your entities.

    Customer class:

    @Entity
    @Table(name = "CUSTOMER")
    public class Customer {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @Column(name = "FIRST_NAME") //Attributes in the entity
        private String firstName;
    
        @Column(name = "LAST_NAME")
        private String lastName;
    
        @Column(name = "ADDRESS")
        private String address;
    
        @ManyToMany(mappedBy = "customer")
        @JoinTable(name = "customer_address", 
            joinColumns = @JoinColumn(name = "customer_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"))
        private List<Address> addresses;
    }
    
    @Entity
    @Table(name = "ADDRESS")
    public class Address {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @Column(name = "STREET_NAME") //Attributes in the entitiy
        private String streetName;
    
        @Column(name = "HOUSE_NUMBER")
        private int houseNumber;
    
        @ManyToMany(mappedBy = "customer")
        @JoinTable(name = "customer_address", 
            joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "customer_id", referencedColumnName = "id"))
        private List<Customer> customer;
    }
    

    In this code annotations are used to provide following information to JPA:

    • @ManyToMany: indicates the type of the relationship
    • @JoinTable: used to specify the table holding the actual relationship data and has following attributes:
      • joinColumns: Defines the column in the intermediate table that refers to the entity class that contains the @ManyToMany annotation. In Customer class, it defines the column that is a foreign key to customer table and in Address class, it defines the column that is a foreign key to address table.
      • inverseJoinColumns: It's the exact opposite of the joinColumn property. Defines the column in the intermediate table that refers to the entity class that is on the other side of the @ManyToMany annotation. In Customer class, it defines the column that is a foreign key to address table and in Address class, it defines the column that is a foreign key to customer table.

    I know that my description is not as readable/understandable as it should be, but you know it's not easy to describe the @JoinTable annotation. Reading the sample code itself and matching column/property names to find the meaning of each one would be an easier approach. Also you can check it in ObjectWeb website (includes a sample too).