0

how do I link via @joincolumn an already existing key from table A with a field in table B.

In detail I have a class server with its key serverId. It has a one-to-one relation to a class license linked by the serverId from the embedded Class LicenseKey. Now the problem is, that my serverId is already defined as a ID and I got the error:

org.hibernate.MappingException: Column 'serverId' is duplicated in mapping for entity 'com.example.jpa.model.Server' (use '@Column(insertable=false, updatable=false)' when mapping multiple properties to the same column)

import jakarta.persistence.*;

@Entity
@Table(name = "server")
public class Server {

@Id
private String serverId;

 @OneToOne
    @JoinColumn(name="version", referencedColumnName="version")
    @JoinColumn(name="serverId", referencedColumnName="serverId")
    private License license;
    
    // getter and setter    
}


@Entity
@Table(name = "license")
public class License {

    @EmbeddedId
    private LicenseKey id;
  // ...
}



@Embeddable
public class LicenseKey implements Serializable  {
    String version;
    String serverId;
 // ...
}

After that I tried to use @JoinColumn(name="serverId", insertable=false, updateable=false, referencedColumnName="serverId") but it does not work and I got more errors. Maybe it is easy and someone can help me here....

Stefan Wuebbe
  • 2,109
  • 5
  • 17
  • 28

2 Answers2

0

The reason for the issue is in the error message itself.

Column 'serverId' is duplicated

As the Server class has field serverId, the JPA has to map that field to a database column serverId. Now the second field license is a separate field in Server class with two @JoinColumns. This means it has to match to two other columns version and serverId(duplicated). This is not possible, right?

From your code, it is difficult to understand what is your database structure. Could you also provide that to suggest a solution.

From what I am assuming, you may either change to @Id private String id or change the serverId name in the @JoinColumn.

Ramanujan R
  • 1,601
  • 2
  • 23
  • 43
  • The ER-Model is: The Server with it's primary-Key "serverId" has an one-to-one relation to License. The License itself is a key-combination of "serverId and version", but this is not the problem. You may forget the version. For me it is about how to connect the given primary field "serverId" from Server with the field "serverId" from the class license! When I combine serverId and version then the key on the server will also be a composite one. – LikeMyDog_22 Jul 30 '23 at 14:55
  • Do you mean the PK of "Server" table should also be a FK which points to "serverId"? For better clarification, you may add the details to your question. A screenshot of the two tables, the create/alter table commands related to these tables etc. This is needed to suggest the changes, because your current code won't work. – Ramanujan R Jul 31 '23 at 02:29
  • Exactly, the PK of Server "serverId" will be the foreign-key of table "license". This is the detail of the question how to join these both fields together. – LikeMyDog_22 Jul 31 '23 at 05:30
0

This might resolve your issue.

LicenseKey

@Embeddable
@Getter
@Setter
public class LicenseKey implements Serializable {

   private Long l_server_id;

   //
}

License

    @Entity
    @Getter
    @Setter
    public class License {
    
        @EmbeddedId
        private LicenseKey licenseKey;
    
        @OneToOne
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
        @MapsId("l_server_id")
        private Server server;
    
    }

Server

 @Entity
    @Getter
    @Setter
    public class Server {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long serverId;
    
        private String serverName;
    
            @OneToOne(cascade = CascadeType.ALL,mappedBy = "server",fetch = FetchType.EAGER)
        private License license;
    
    }

This is going to create the table structure like this

Hibernate: create table license (l_server_id bigint not null, primary key (l_server_id)) engine=InnoDB
Hibernate: create table server (server_id bigint not null auto_increment, server_name varchar(255), primary key (server_id)) engine=InnoDB
Hibernate: alter table license add constraint FKkope30d18c3etsmqjipi6yrw9 foreign key (l_server_id) references server (server_id)
rahulP
  • 244
  • 2
  • 6
  • And how do I access the license via Server-Table in direct way? If I apply my whish in Database without JPA it is pretty simple, but JPA seems to be rather obstructive. I am confused that it is that difficult. – LikeMyDog_22 Jul 31 '23 at 11:38
  • I have edited the answer. you can use fetchType as Eager to directly fetch the License data whenever you will query the server table. – rahulP Jul 31 '23 at 12:33
  • This is working for one Key @MapsId("l_server_id"). But MapsId is not repeatable for a second value version of the composite key. How could that work ? – LikeMyDog_22 Jul 31 '23 at 14:15
  • MapsId is mapping the Id. For other parameters try to use @joincolumn – rahulP Jul 31 '23 at 14:28
  • Then it is also working, if I do it right. Would it be helpful if i write the complete code here ? – LikeMyDog_22 Jul 31 '23 at 15:05
  • From which entity this version is coming? Add that detail as well. – rahulP Jul 31 '23 at 19:22
  • From both of course – LikeMyDog_22 Aug 01 '23 at 06:01
  • Can you give the details of this version field? where this is present n all – rahulP Aug 01 '23 at 06:16
  • @Column(name = "VERSION") private String version; // In Server and in License – LikeMyDog_22 Aug 01 '23 at 06:47
  • In general, I think @primarykeyjoincolumn on server could also help to solve this issue. – LikeMyDog_22 Aug 01 '23 at 06:49
  • I am not getting one point. If your version field is part of server entity they how you are going to keep two version values for same serverid? If it is not possible then why are you trying to keep embedded id of serverId and versionId? – rahulP Aug 01 '23 at 08:03
  • 1
    You are absolutely right, the model is not correct here. – LikeMyDog_22 Aug 01 '23 at 08:07