Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

260
Vistas
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 Respuestas
Responde la pregunta

0

Try annotating also author?

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

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda