1

I have two classes that I want integrate via Hibernate:

  1. Goal class, which contains User's goals. It backed by "DIC_GOAL" table.
  2. Role class, which contains User's access. It backed by "ROLES" table

In my Database structure I have table "Goal" which has field "ROLE_ID". This field points on Role's table Primary Key "ID". So, every row (entity) in Goal table maps to Role's row (entity) One by One.

So, I want to join Role class to Goal class to be able to represent extended Rolename for every Goal, which is placed in Role class. I use the below code to do this in Hibernate (in Goal class):

   @OneToOne
   @JoinColumn (name="role_id")
   Role role;

And getting error: Repeated column in mapping for entity: com.platform.entity.Goal column: role_id (should be mapped with insert="false" update="false") Plese help me investigate this error?

ROLES table

create table MAPP.ROLES
(
  id       INTEGER generated always as identity,
  rolename VARCHAR2(255),
  descr    VARCHAR2(255)
)

GOAL Table

create table MAPP.DIC_GOAL
(
  id      INTEGER generated always as identity,
  descr   NVARCHAR2(255),
  role_id INTEGER not null,
  vl      NUMBER
)

Goal class

package com.platform.entity;

@Entity
@Table(name="dic_goal", schema="MAPP")
public class Goal {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "ID", nullable = false)
   private Long id;

   @Column(name = "DESCR", length = 255, nullable = false)
   public String descr;

   @Column(name = "ROLE_ID", nullable = false)
   public int role_id;

   // Here it is!
   @OneToOne
   @JoinColumn (name="role_id")
   Role role;

   @Column(name = "VL")
   private float vl;

   public Long getId() {
       return id;
   }

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

   public String getDescr() {
       return descr;
   }

   public void setDescr(String descr) {
       this.descr= descr;
   }

   public float getVl() {
       return vl;
   }

   public void setVl(float vl) {
       this.vl = vl;
   }

    @Override
    public String toString() {
        return "ID=" + id + " DESCR=" + descr + " VL=" + vl;
    }

}

Role class

package com.platform.entity;

@Entity
@Table(name="roles", schema="MAPP")
public class Role implements GrantedAuthority {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;

    @Column(name = "ROLENAME", length = 255, nullable = false)
    @Size(min=5, message="Не меньше 5 знаков")
    private String roleName;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name="user_roles", schema="MAPP",
            joinColumns = @JoinColumn(name="role_id"),
            inverseJoinColumns = @JoinColumn(name="user_id")
    )
    private Set<User> users;

    public String getName() {
        return roleName;
    }

    public void setName(String name) {
        this.roleName = name;
    }

    public Long getId() {
        return id;
    }

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


    @Override
    public String getAuthority() {
        return getName();
    }

    @Override
    public String toString() {
        return this.getName();
    }


}
5
  • The reason is simple: you are mapping the column role_id to 2 different properties, the Role role and int role_id. What are you trying to accomplish with the int role_id field? Commented Mar 10, 2020 at 15:26
  • Role_ID is a secondary key in ROLES table which points to ID in GOAL table. Its here in Goal class to replresent Role's ID. So as I take, I have to replace it just to role object? Commented Mar 10, 2020 at 15:47
  • You can keep just the role object. If you need access to the role id, without fearing that Hibernate might run extra queries in the background, you can also keep the role_id field, marking it as @Column(name = "ROLE_ID", nullable = false, insert="false" update="false"), just as the error suggests! Don't worry, this is quite a common practice - hence the suggestion in the error message. Commented Mar 10, 2020 at 16:00
  • @NikosParaskevopoulos Thank you. Both way of your advices works. But which restrictions do I get with "insert="false" update="false""? Commented Mar 11, 2020 at 5:39
  • With insert="false" update="false" the JPA provider (Hibernate) will ignore changes to the Java field when writing state back to the database. So, int role_id will be populated from the ROLE_ID column when reading from the database. But any changes to it will not be written back, neither when updating an existing entity nor when inserting a new one. Commented Mar 11, 2020 at 8:52

1 Answer 1

1

As Nikos Paraskevopoulos corretly mentioned: The reason is simple: you are mapping the column role_id to 2 different properties, the Role role and int role_id So I removed int role_id and replaced it by linked Role object.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.