我试图使用JPA来坚持用户对象并出现问题。用户引用一组角色对象,它是一个抽象类,它有多个子类。目前,我只有一个 - 管理员。JPA:坚持引用抽象类集合的对象
下面是用户等级:
@Entity(name = "USERS")
public class User implements Serializable{
@Id
@Column(name = "USERNAME")
private String username;
@Column(name = "PASSWORD")
private String password;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "ROLE_ID")
private Set<Role> roles;
public User(){
roles = new HashSet<Role>();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Set<Role> getRoles(){
return roles;
}
public void setRoles(Set<Role> roles){
this.roles = roles;
}
public void addRole(Role role){
roles.add(role);
}
}
这里是角色:
@Entity(name = "ROLES")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Role implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ROLE_ID")
int id;
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
}
这里是联系(空的现在,但稍后将添加的东西出来)。
@Entity(name = "ADMINS")
public class Admin extends Role{
}
现在这里是代码,我创建的对象,并试图坚持他们。我想能够坚持一个用户对象,并让它的角色对象自动保持 - 我相信在用户中的CascaseType.ALL这样做。
public class JPAManager {
public void persist(Serializable s){
EntityManagerFactory emf = getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
em.persist(s);
et.commit();
em.close();
emf.close();
}
protected EntityManagerFactory getEntityManagerFactory(){
return Persistence.createEntityManagerFactory("main");
}
}
最后,这里是主要的方法:
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
User user = new User();
user.setUsername("Chris842");
user.setPassword("123456");
user.setFirstName("Chris");
user.setLastName("Jones");
user.addRole(new Admin());
UserDAO dao = context.getBean("userDAO", UserDAO.class);
dao.persist(user);
System.out.println("Done");
}
编辑:第一个答案之后,我尝试这样做的主要方法,但得到了同样的异常:
Admin admin = new Admin();
admin.setId(1);
user.addRole(admin);
当运行上面的过程,我的数据库中创建了两个名为USERS,ROLES和ADMINS的表。用户和角色/ ADMINS之间似乎没有联系。我期望在USERS中有一个ROLE_ID(或者在ROLES中有一个USERNAME),但是两者都没有。
这是堆栈跟踪。谢谢你的帮助。我很感激它,一直试图弄清楚这个问题已有好多年了!
Hibernate:
select
hibernate_sequence.nextval
from
dual
Hibernate:
insert
into
USERS
(PASSWORD, FIRST_NAME, LAST_NAME, USERNAME)
values
(?, ?, ?, ?)
Hibernate:
insert
into
ROLES
(ROLE_ID)
values
(?)
Hibernate:
insert
into
ADMINS
(ROLE_ID)
values
(?)
Hibernate:
update
ROLES
set
ROLE_ID=?
where
ROLE_ID=?
Exception in thread "main" javax.persistence.RollbackException: Error while commiting the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
at com.fdm.tradingplatform.dao.JPAManager.persist(JPAManager.java:21)
at com.fdm.tradingplatform.dao.UserDAO.persist(UserDAO.java:21)
at Main.main(Main.java:28)
Caused by: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
... 3 more
Caused by: java.sql.BatchUpdateException: ORA-01722: invalid number
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10768)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
... 11 more
在阅读本文之后5分钟内解决问题,花费时间后!谢谢! :) 我只需要稍微改变Role中的User属性。我对它的注释是(在)ManyToOne和(在)JoinColumn(name =“USER_ID”)。 (at)Column本身在User上导致了User类中mappedBy属性上的编译错误。 – Chris 2014-08-29 09:32:22
无法将@符号放在上面的评论中 - 所以我以为我试图给用户加标签。 – Chris 2014-08-29 09:32:45
@Chris你说得对,我编辑了我的答案。 – WilQu 2014-08-29 09:35:48