2017-08-09 84 views
0

我在春季4,Oracle 11gr2学习hibernate orm,而且我有点陷入了多对多的关系问题。我指的是下面的链接 - https://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/休眠多对多使用可嵌入

但我不能使它的工作。

这是我的数据库表。 enter image description here

这里是我的实体POJO风格。

Account.java包含用户帐户信息。

import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.SequenceGenerator; 
import javax.persistence.Table; 
import javax.persistence.UniqueConstraint; 

@Entity 
@Table(name="account", 
    uniqueConstraints={ 
     @UniqueConstraint(columnNames={"email"}), 
     @UniqueConstraint(columnNames={"nickname"}) 
    } 
) 
public class Account { 

    private int accountId; 
    private String email; 
    private String password; 
    private String nickname; 
    private int enabled; 
    private Set<UserRole> userRoles = new HashSet<UserRole>(0); 

    public Account() {} 

    public Account(String email, String password, String nickname, int enabled) { 
     this.email = email; 
     this.password = password; 
     this.nickname = nickname; 
     this.enabled = enabled; 
    } 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_account") 
    @SequenceGenerator(name="seq_account", sequenceName="seq_account", allocationSize=1) 
    @Column(name="account#", unique=true, nullable=false) 
    public int getAccountId() { 
     return accountId; 
    } 

    public void setAccountId(int accountId) { 
     this.accountId = accountId; 
    } 

    @Column(name="email", unique=true, nullable=false) 
    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    @Column(name="passwd", nullable=false) 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    @Column(name="nickname", unique=true, nullable=false) 
    public String getNickname() { 
     return nickname; 
    } 

    public void setNickname(String nickname) { 
     this.nickname = nickname; 
    } 

    @Column(name="enabled", nullable=false) 
    public int getEnabled() { 
     return enabled; 
    } 

    public void setEnabled(int enabled) { 
     this.enabled = enabled; 
    } 

    @OneToMany(mappedBy="pk.account", fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    public Set<UserRole> getUserRoles() { 
     return userRoles; 
    } 

    public void setUserRoles(Set<UserRole> userRoles) { 
     this.userRoles = userRoles; 
    } 





} 

RoleDef.java包含用于授权的角色定义。

import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.SequenceGenerator; 
import javax.persistence.Table; 
import javax.persistence.UniqueConstraint; 


@Entity 
@Table(name="role_def", 
    [email protected](columnNames={"role_nm"}) 
) 
public class RoleDef { 

    private int roleId; 
    private String roleName; 
    private Set<UserRole> userRoles = new HashSet<UserRole>(0); 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_role_def") 
    @SequenceGenerator(name="seq_role_def", sequenceName="seq_role_def", allocationSize=1) 
    @Column(name="role#", unique=true, nullable=false) 
    public int getRoleId() { 
     return roleId; 
    } 
    public void setRoleId(int roleId) { 
     this.roleId = roleId; 
    } 

    @Column(name="role_nm", unique=true, nullable=false) 
    public String getRoleName() { 
     return roleName; 
    } 
    public void setRoleName(String roleName) { 
     this.roleName = roleName; 
    } 

    @OneToMany(mappedBy="pk.roleDef", fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    public Set<UserRole> getUserRoles() { 
     return userRoles; 
    } 
    public void setUserRoles(Set<UserRole> userRoles) { 
     this.userRoles = userRoles; 
    } 



} 

UserRole.java与Account和RoleDef相互连接。

import java.io.Serializable; 

import javax.persistence.AssociationOverride; 
import javax.persistence.AssociationOverrides; 
import javax.persistence.EmbeddedId; 
import javax.persistence.Entity; 
import javax.persistence.JoinColumn; 
import javax.persistence.Table; 
import javax.persistence.Transient; 

@Entity 
@Table(name="user_role") 
@AssociationOverrides(value={ 
     @AssociationOverride(name="pk.account", joinColumns={@JoinColumn(referencedColumnName="account#")}), 
     @AssociationOverride(name="pk.roleDef", joinColumns={@JoinColumn(referencedColumnName="role#")}) 
}) 
public class UserRole implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    private UserRoleId pk = new UserRoleId(); 

    @EmbeddedId 
    public UserRoleId getPk() { 
     return pk; 
    } 

    public void setPk(UserRoleId pk) { 
     this.pk = pk; 
    } 

    @Transient 
    public Account getAccount(){ 
     return pk.getAccount(); 
    } 

    public void setAccount(Account account){ 
     pk.setAccount(account); 
    } 

    @Transient 
    public RoleDef getRoleDef(){ 
     return pk.getRoleDef(); 
    } 

    public void setRoleDef(RoleDef roleDef){ 
     pk.setRoleDef(roleDef); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) 
      return false; 

     if (o == null || getClass() != o.getClass()) 
      return false; 

     UserRole that = (UserRole) o; 

     if (getPk() != null ? 
       !getPk().equals(that.getPk()) : that.getPk() != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     return (getPk() != null ? getPk().hashCode() : 0); 
    } 





} 

UserRoleId.java表示在UserRole.java

import java.io.Serializable; 

import javax.persistence.Embeddable; 
import javax.persistence.ManyToOne; 

@Embeddable 
public class UserRoleId implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    private Account account; 
    private RoleDef roleDef; 

    @ManyToOne 
    public Account getAccount() { 
     return account; 
    } 
    public void setAccount(Account account) { 
     this.account = account; 
    } 

    @ManyToOne 
    public RoleDef getRoleDef() { 
     return roleDef; 
    } 
    public void setRoleDef(RoleDef roleDef) { 
     this.roleDef = roleDef; 
    } 

    @Override 
    public int hashCode() { 
     int result; 
     result = (account!= null ? account.hashCode() : 0); 
     result = 31 * result + (roleDef != null ? roleDef.hashCode() : 0); 
     return result; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) 
      return false; 

     if (o == null || getClass() != o.getClass()) 
      return false; 

     UserRoleId that = (UserRoleId) o; 

     if (account != null ? 
       !account.equals(that.getAccount()) : that.getAccount() != null) 
      return false; 

     if (roleDef != null ? 
       !roleDef.equals(that.getRoleDef()) : that.getRoleDef() != null) 
      return false; 

     return true; 
    } 


} 

和运行代码的主键:

Account account = new Account(); 
account.setEmail("[email protected]"); 
account.setPassword("1234"); 
account.setNickname("playmaker"); 
account.setEnabled(0); 

Session session = sessionFactory.getCurrentSession(); 

// Get normal user role information. 
Query query = session.createQuery("from RoleDef a where a.roleName = :roleName"); 
query.setParameter("roleName", ROLE_USER); 
@SuppressWarnings("unchecked") 
List<RoleDef> roleList = (List<RoleDef>)query.list(); 
RoleDef roleDef = roleList.get(0); 

UserRole userRole = new UserRole(); 

userRole.setAccount(account); 
userRole.setRoleDef(roleDef); 

account.getUserRoles().add(userRole); 

session.save(account); 

当我运行的代码,这里是错误堆栈的一部分:

Hibernate: select userrole_.account_account#, userrole_.roleDef_role# from user_role userrole_ where userrole_.account_account#=? and userrole_.roleDef_role#=? 
INFO : jdbc.audit - 5. PreparedStatement.new PreparedStatement returned 
INFO : jdbc.audit - 5. Connection.prepareStatement(select userrole_.account_account#, userrole_.roleDef_role# from user_role userrole_ where userrole_.account_account#=? and userrole_.roleDef_role#=?) returned [email protected] 
INFO : jdbc.audit - 5. PreparedStatement.setInt(1, 3) returned 
INFO : jdbc.audit - 5. PreparedStatement.setInt(2, 23) returned 
INFO : jdbc.sqlonly - select userrole_.account_account#, userrole_.roleDef_role# from user_role userrole_ where userrole_.account_account#=3 
and userrole_.roleDef_role#=23 
ERROR: jdbc.audit - 5. PreparedStatement.executeQuery() select userrole_.account_account#, userrole_.roleDef_role# from user_role userrole_ where userrole_.account_account#=3 and userrole_.roleDef_role#=23 
java.sql.SQLSyntaxErrorException: ORA-00904: "USERROLE_"."ROLEDEF_ROLE#": 부적합한 식별자 

任何想法solv这个问题?

谢谢。

回答

1

ORA-00904很可能意味着您引用的数据库中不存在的列。

ORA-00904 string: invalid identifier 

Cause: The column name entered is either missing or invalid. 

Action: Enter a valid column name. A valid column name must begin with a letter, be less than or equal to 30 characters, and consist of only alphanumeric characters and the special characters $, _, and #. 

If it contains other characters, then it must be enclosed in double quotation marks. It may not be a reserved word. 

see here

在查询看你想选择"USERROLE_"."ROLEDEF_ROLE#"但看着你的数据模型只起了"USERROLE_"."ROLEDEF#"列。

我觉得

@AssociationOverrides(value={ 
    @AssociationOverride(name="pk.account", joinColumns={@JoinColumn(name="account#", referencedColumnName="account#")}), 
    @AssociationOverride(name="pk.roleDef", joinColumns={@JoinColumn(name="role#", referencedColumnName="role#")}) 

应该解决您的问题,如在原来的代码,你只覆盖referencedColumnName,而不是列名在user_role的本身,因此Hibernate试图拿出按照惯例巫右列名不适合你的Datamodel。

+0

谢谢汤姆!我终于知道这是为什么发生。现在是时候继续前进:D – PLAYMAKER