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?
Try annotating also author?
@ManyToOne
@JoinColumn(name="author")
private User author;
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
}
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.