Many-many relationship with extra columns in JPA

In the previous tutorial, I introduced you to the @ManyToMany annotation to express many-to-many relationships between any two tables in the database, such as a developer can work on multiple projects and vice versa: a project can have many developers. But in fact, we need to save some additional information regarding these two tables. For example, in a project, a developer can be assigned to do a task. In this case, how do we represent by entities in JPA? In this tutorial, let’s learn together.

First, I will create a Maven project as an example:

Many-many relationship with extra columns in JPA

I will use Hibernate as JPA implementation so I will add Hibernate dependency as follows:

MySQL Connector:

Project Lombok:

Assume, now I define the structure of the two tables developer and project as follows:

To illustrate the many-to-many relationship between two tables above, I also define a joinTable as follows:

As the example at the beginning of this tutorial, now I want to store more information: what the developer will do in the project. As you can see, here we can only save this information in the joinTable. So, I’ll add a column in the developer_project table as follows:

To represent these tables via entities, we cannot use the @ManyToMany annotation anymore. Because if you use the @ManyToMany annotation, the joinTable’s information will be hidden, and therefore we cannot display the information of ‘task’ column in developer_project table.

Solution for this problem, we can use @OneToMany annotation bidirectional way. How is it in detail? Keep continuing reading.

To use the bidirectional way with @OneToMany annotation, we need to do the following:

  • First, you need to build an entity for the developer_project table.

Since the developer_project table contains a Composite Primary Key, we will define a class with the @Embeddable annotation as follows:

Entity for the developer_project table will have the following contents:

In this entity, I used the @ManyToOne annotation to express the many-to-one relationship between the developer_project table and the developer and project tables.

Here, I also used an @MapsId annotation. This annotation is used in the entity that declared the @EmbeddedId annotation to map to the primary key column defined in the Embeddable object. Therefore, the value of the @MapsId annotation will be the variable name in the @Embeddable object map with the primary key column.

  • The next step is to define the entity for the developer and project tables.

The entities of these two tables will use @OneToMany annotation:

OK, so we have already defined the entities. Now try running an example.

I will add the configuration file for JPA, persistence.xml, located in the /src/main/resources/META-INF directory with the following contents:

Suppose, you have the following data in your database:

Many-many relationship with extra columns in JPA

then when running the following example:

the result will be:

2 thoughts on “Many-many relationship with extra columns in JPA

  1. Hello Sir,

    Irrespective of the column names that i mentioned @Column, in DB i am seeing only default one

    case -1)
    @Column(name = “developer_id”)
    private Integer developerId;

    @Column(name = “project_id”)
    private Integer projectId;

    CREATED Columns are : developer_id, project_id

    case-2) if i change column names such as
    @Column(name = “developer_id_1”)
    private Integer developerId;

    @Column(name = “project_id_1”)
    private Integer projectId;

    still generating same column names developer_id, project_id

    can you please help me here.


Add Comment