Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

262
Views
JPA Entity with two fields of the same type

I'm trying to have 2 fields of the same domain class in my entity and I'm getting this error:

org.hibernate.MappingException: Could not determine type for: com.packt.webapp.domain.User, at table: opinions, for columns: [org.hibernate.mapping.Column(author)]

My entities:

@Entity
@Table(name="opinions")
public class Opinion {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @NotNull
    private String text;
    @NotNull
    private String date;
    @ManyToOne
    @JoinColumn(name="commented_user")
    private User writtenTo;
    private User author;

@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String username;
    private String password;
    @OneToMany(mappedBy="writtenTo")
    private List<Opinion> opinions;

I just want to map opinions to commented users and storage author of comment in author field. When I remove author field, everything works. Whats wrong with this example?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Try annotating also author?

@ManyToOne
@JoinColumn(name="author")
private User author;
over 4 years ago · Santiago Trujillo Report

0

It's complaining that it doesn't know how to map the author field. You can provide a mapping similar to how you mapped writtenTo. An opinion has one author and an author can have authored many opinions.

If you would like to ignore a field for mapping, annotate it with @Transient. The transient annotation prevents that field from being persisted to the database otherwise you have to map it like so:

Opinion entity:

@Entity
@Table(name="opinions")
public class Opinion {

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

    @NotNull
    private String text;

    @NotNull
    private String date;

    @ManyToOne
    @JoinColumn(name="commented_user")
    private User writtenTo;

    // map author to User entity
    @ManyToOne
    @JoinColumn(name="authored_user")
    private User author;

    // getters and setters
}

User entity:

@Entity
@Table(name="user")
public class User {

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

    private String username;

    private String password;

    @OneToMany(mappedBy="writtenTo")
    private List<Opinion> opinions;

    // map opinions to the author
    @OneToMany(mappedBy="author")
    private List<Opinion> authoredOpinions;

    // getters and setters
}
over 4 years ago · Santiago Trujillo Report

0

Just apply the @ManyToOne annotation at both the User fields.

@ManyToOne
@JoinColumn(name="commented_user")
private User writtenTo;
@ManyToOne
@JoinColumn(name="author")
private User author;

But there is a more flexible solution to problems like this. Replace the @OneToMany and @ManyToOne relations by @ManyToMany ones. Create a User and a Role entity (with descendats for the ones with specific fields). A User could have many roles (writer, author, etc) and a Role could be played by many users. In this case you can change your mind and create/remove/attach/detach roles dynamically without any data structure changing on the existing tables.

@Entity
public class User
{
  @Id
  private Long id;
  @Column
  private String name;
  @ManyToMany
  @JoinTable(
      name="User_Role",
      joinColumns=@JoinColumn(name="UserID", referencedColumnName="ID"),
      inverseJoinColumns=@JoinColumn(name="RoleID", referencedColumnName="ID"))
  private List<Role> roles;
}

@Entity
public class Role
{
  @Id
  private Long id;
  @Column
  private String name;
  @ManyToMany( mappedBy="roles" )
  private List<User> users;
}

And you can get/check the user roles by role ids/names using a utility class:

puclic class RoleUtility
{
  public Role getUserRoleByName( User user_, String roleName_ )
  {
    User retRole = null;
    Iterator<Role> i = roles_.iterator();
    while ( ( retRole == null ) && i.hasNext() )
    {
      Role role = (Role) i.next();
      if ( roleName_.isEqual( role.getName ) )
        retRole = role;
    }
    return retRole;
  }
}

The client code to checking a role:

User user = ...
Role role = RoleUtility.getRoleByName( user.getRoles(), roleName );

Stay at you example with this solution you can add a censor/moderator to the opinion or something like that without any data structure changing.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!