Hibernate Composite Table and Key Issues
I am trying to get hibernate to work with a composite table. Basically there is a users table, roles table, and a composite table called userroles which connects both. The query I get from getting a user with roles eagerly outputs what is below. I keep getting stackoverflow errors, or null exception. My question is why does the columns product two userid and roleid outputs in Oracle?
select
this_.ID as ID0_1_,
this_.DATECREATED as DATECREA2_0_1_,
this_.EMAIL as EMAIL0_1_,
this_.ENABLED as ENABLED0_1_,
this_.FIRSTNAME as FIRSTNAME0_1_,
this_.LASTNAME as LASTNAME0_1_,
this_.PASSWORD as PASSWORD开发者_JAVA技巧0_1_,
this_.SALT as SALT0_1_,
this_.USERNAME as USERNAME0_1_,
userroles2_.USERID as USERID3_,
userroles2_.ROLEID as ROLEID3_,
userroles2_.ROLEID as ROLEID3_0_,
userroles2_.USERID as USERID3_0_
from
CISCO.USERS this_
inner join
CISCO.USERROLES userroles2_
on this_.ID=userroles2_.USERID
where
this_.USERNAME='mike'
My classes are below.
User.java
@Entity
@Table(name = "USERS", schema = "CISCO")
@SuppressWarnings("serial")
public class User implements Serializable {
/**
* Attribute id.
*/
private long id;
/**
* Attribute username.
*/
private String username;
/**
* Attribute password.
*/
private String password;
/**
* Attribute enabled.
*/
private Long enabled;
/**
* Attribute salt.
*/
private String salt;
/**
* Attribute first name.
*/
private String firstName;
/**
* Attribute last name.
*/
private String lastName;
/**
* Attribute email.
*/
private String email;
/**
* Attribute email.
*/
private Date dateCreated;
/**
* @return id
*/
@Basic
@Id
@Column(name = "ID")
public long getId() {
return id;
}
/**
* @param username new value for id
*/
public void setId(long id) {
this.id = id;
}
/**
* @return username
*/
@Basic
@Column(name = "USERNAME", length = 50)
public String getUsername() {
return username;
}
/**
* @param username new value for username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return password
*/
@Basic
@Column(name = "PASSWORD", length = 50)
public String getPassword() {
return password;
}
/**
* @param password new value for password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @return enabled
*/
@Basic
@Column(name = "ENABLED")
public Long getEnabled() {
return enabled;
}
/**
* @param enabled new value for enabled
*/
public void setEnabled(Long enabled) {
this.enabled = enabled;
}
/**
* @return salt
*/
@Basic
@Column(name = "SALT", length = 25)
public String getSalt() {
return salt;
}
/**
* @param salt new value for salt
*/
public void setSalt(String salt) {
this.salt = salt;
}
/**
* @return first name
*/
@Basic
@Column(name = "FIRSTNAME", length = 100)
public String getFirstName() {
return firstName;
}
/**
* @param first name new value for first name
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return last name
*/
@Basic
@Column(name = "LASTNAME", length = 100)
public String getLastName() {
return lastName;
}
/**
* @param last name new value for last name
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* @return email
*/
@Basic
@Column(name = "EMAIL", length = 50)
public String getEmail() {
return email;
}
/**
* @param email new value for email
*/
public void setEmail(String email) {
this.email = email;
}
/**
* @return dateCreated
*/
@Basic
@Column(name = "DATECREATED")
public Date getDateCreated() {
return dateCreated;
}
/**
* @param dateCreated new value for dateCreated
*/
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
private List<UserRole> userRoles;
/**
* Get the list of User Roles
*/
@OneToMany(fetch=FetchType.EAGER, mappedBy="userRolePK.user")
public List<UserRole> getUserRoles() {
return this.userRoles;
}
/**
* Set the list of User Roles
*/
public void setUserRoles(List<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
Role.java
@Entity
@Table(name = "ROLES", schema = "CISCO")
@SuppressWarnings("serial")
public class Role implements Serializable {
/**
* Attribute id.
*/
private Long id;
/**
* Attribute name.
*/
private String name;
/**
* List of Userroles
*/
private List<UserRole> userRoles = null;
/**
* @return id
*/
@Basic
@Id
@Column(name = "ID")
public Long getId() {
return id;
}
/**
* @param id new value for id
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return name
*/
@Basic
@Column(name = "NAME", length = 20)
public String getName() {
return name;
}
/**
* @param name new value for name
*/
public void setName(String name) {
this.name = name;
}
/**
* Get the list of Userroles
*/
@OneToMany(fetch=FetchType.LAZY, mappedBy="userRolePK.role")
public List<UserRole> getUserRoles() {
return this.userRoles;
}
/**
* Set the list of Userroles
*/
public void setUserRoles(List<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
UserRole.java
@Entity
@Table(name = "USERROLES", schema = "CISCO")
@SuppressWarnings("serial")
public class UserRole implements Serializable {
/**
* Primary key
*/
private UserRolePK userRolePK;
/**
* Get the primary key
*/
@Basic
@Id
public UserRolePK getUserRolePK() {
return this.userRolePK;
}
/**
* set the primary key
*/
public void setUserRolePK(UserRolePK userRolePK) {
this.userRolePK = userRolePK;
}
@SuppressWarnings("serial")
@Embeddable
public static class UserRolePK implements Serializable {
/**
* Attribute users
*/
private User user;
/**
* Attribute roles
*/
private Role role;
/**
* get users
*/
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "USERID")
public User getUser() {
return this.user;
}
/**
* set users
*/
public void setUser(User user) {
this.user = user;
}
/**
* get roles
*/
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "ROLEID")
public Role getRole() {
return this.role;
}
/**
* set roles
*/
public void setRole(Role roles) {
this.role = role;
}
/**
* calculate hashcode
*/
@Override
public int hashCode()
{
//TODO : implement this method
return super.hashCode();
}
/**
* equals method
*/
@Override
public boolean equals(Object object)
{
//TODO : implement this method
return super.equals(object);
}
}
}
The call that gets the data is
public List<T> findByCriteria(Criteria criteria, List<Criterion> criterions, IList list) {
if(criterions != null)
{
for(Criterion c : criterions)
{
criteria.add(c);
}
}
criteria.setProjection(Projections.rowCount());
list.setTotal(((Integer)criteria.uniqueResult()).intValue());
logger.debug("Count:" + list.getTotal());
if(list.getTotal() > 0)
{
criteria.setProjection(null);
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
criteria.setFirstResult((list.getPage() - 1) * list.getPageSize()).setMaxResults(list.getPageSize());
if(list.getSortBy() != null && list.getSortBy().length() > 0) {
Order order = null;
if(list.getOrderBy().equalsIgnoreCase("asc"))
order = Order.asc(list.getSortBy());
else
order = Order.desc(list.getSortBy());
criteria.addOrder(order);
}
return criteria.list();
}
return new ArrayList<T>();
}
I'm not sure about the cause of this strange query, but I wonder why do you map your join table as an entity instead of using @ManyToMany
?
@Entity
@Table(name = "USERS", schema = "CISCO")
@SuppressWarnings("serial")
public class User implements Serializable {
...
@ManyToMany
@JoinTable(name = "USERROLES",
joinColumns = @JoinColumn(name = "USERID"),
inverseJoinColumns = @JoinColumn(name = "ROLEID")
)
public List<Role> getRoles() { ... }
public void setRoles(List<Role> roles) { ... }
}
@Entity
@Table(name = "ROLES", schema = "CISCO")
@SuppressWarnings("serial")
public class Role implements Serializable {
...
// I'm not sure if you need this relationship to be bidirectional,
// but if you actually need here is another side
@ManyToMany(mappedBy = "roles")
public List<User> getUsers() { ... }
public void setUsers(List<User> users) { ... }
}
See also:
- 2.2.5.3.2. Many-to-many
I basically went that route. I was using the default schema Spring says to use for default setup. I went ahead and created a Users/Roles/UserRoles table like you said above. Below is what I have in my User.cs class and it joins it correctly.
@OneToMany(fetch=FetchType.EAGER)
@JoinTable(
name="UserRoles",
joinColumns = @JoinColumn( name="USERID"),
inverseJoinColumns = @JoinColumn( name="ROLEID")
)
public List<Role> getRoles() {
return this.roles;
}
精彩评论