使用embeddable

时间:2017-08-09 03:01:16

标签: java spring hibernate

我正在研究春天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", 
    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#": 부적합한 식별자

有什么想法解决这个问题?

感谢。

1 个答案:

答案 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.

TONS

查看您的查询,您尝试选择"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。