我正在研究春天4,Oracle 11gr2的hibernate orm,我有点陷入很多关系问题。我指的是以下链接 - https://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
但我不能让它发挥作用。
以下是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",
uniqueConstraints=@UniqueConstraint(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;
}
}
与Account和RoleDef互连的UserRole.java。
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("asdasd123@google.com");
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 net.sf.log4jdbc.PreparedStatementSpy@1ba4ffed
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#": 부적합한 식별자
有什么想法解决这个问题?
感谢。
答案 0 :(得分: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.
查看您的查询,您尝试选择"USERROLE_"."ROLEDEF_ROLE#"
,但查看您的Datamodel,只有"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本身中的Columnname,因此Hibernate试图根据惯例提出正确的列名,这不适合您的Datamodel。