[英]org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property (with session.merge)
I have a problem. 我有个问题。 I get error in my app: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property
我在我的应用程序中遇到错误: org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性分配ID
My pojos User: 我的pojos用户:
@Entity
@Table(name = "user")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User implements Serializable {
private static final long serialVersionUID = -5415891222321582213L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "userId", length = 100)
private int userId;
...
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private UserDetail userDetail;
UserDetail: 用户详细信息:
@Entity
@Table(name = "userdetail")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class UserDetail implements Serializable {
private static final long serialVersionUID = 2155190440305692224L;
@Id
@GenericGenerator(
name = "gen",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "user")
)
@GeneratedValue(generator = "gen")
@Column(name = "userId", length = 100)
private int userId;
...
@OneToOne
@PrimaryKeyJoinColumn
private User user;
Table User: 表用户:
CREATE TABLE `user` (
`userId` INT(100) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
`surname` VARCHAR(255) NULL DEFAULT NULL,
`email` VARCHAR(255) NULL DEFAULT NULL,
`password` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`userId`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
Table UserDetail 表用户详细信息
CREATE TABLE `userdetail` (
`userId` INT(100) NOT NULL,
`country` VARCHAR(255) NULL DEFAULT NULL,
`city` VARCHAR(255) NULL DEFAULT NULL,
`address` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`userId`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
DAO Layer: DAO层:
private Session session = HibernateUtil.getHibernateUtil().getSession();
@Override
public void create(T t) throws DaoException {
Object object = session.merge(t);
session.save(object);
log.info("Update: " + t);
}
Service Layer 服务层
private Session session = HibernateUtil.getHibernateUtil().getSession();
private Transaction transaction = null;
private Dao<T> dao = new BaseDao<T>();
@Override
public void create(T t) throws DaoException {
try {
transaction = session.beginTransaction();
dao.create(t);
transaction.commit();
log.info("Create: " + t);
} catch (HibernateException e) {
log.error("Error creating " + getPersistentClass() + " in Dao " + e);
transaction.rollback();
throw new DaoException(e);
}
}
Class with saving User 具有保存用户的类
User user = new User(name, surname, email, password);
UserDetail userDetail = new UserDetail(country, city, address);
user.setUserDetail(userDetail);
userDetail.setUser(user);
userService.create(user);
HiberUtil HiberUtil
public class HibernateUtil {
private static Logger log = Logger.getLogger(HibernateUtil.class);
private static HibernateUtil util = null;
private static SessionFactory sessionFactory = null;
private static final ThreadLocal<Session> sessions = new ThreadLocal<Session>();
private HibernateUtil() {
try {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
log.info("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
log.info("Hibernate serviceRegistry created");
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable e) {
log.error("Initial SessionFactory creation failed. " + e);
System.exit(0);
}
}
public Session getSession () {
Session session = sessions.get();
if (session == null) {
session = sessionFactory.openSession();
sessions.set(session);
}
return session;
}
public static synchronized HibernateUtil getHibernateUtil(){
if (util == null){
util = new HibernateUtil();
}
return util;
}
}
If i change in DAO layer: 如果我在DAO层中更改:
@Override
public void create(T t) throws DaoException {
session.save(t);
log.info("Create: " + t);
}
I get error: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 我收到错误消息: org.hibernate.HibernateException:非法尝试将一个集合与两个打开的会话相关联
So I have 4 questions: 所以我有四个问题:
If I understood correctly, when userdeteil save userId from User is null because UserId don't get icnrement Id from Table, it's true? 如果我理解正确,那么当Userdeteil从User中保存userId为null时(因为UserId无法从Table中获取icnrement ID),这是真的吗?
Needed session.merge here or not 需要session.merge在这里与否
If merge is needed, how correct org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property 如果需要合并,如何正确的org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性分配ID
If merge is no needed, how correct "org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions" 如果不需要合并,如何正确纠正“ org.hibernate.HibernateException:非法尝试将一个集合与两个打开的会话相关联”
Note: Delet with merge is good, create with merge other Entity (not User and not UserDeteil) is good. 注意:删除合并是好的,创建合并其他实体(不是User而不是UserDeteil)是好的。
To get it work, remove Object object = session.merge(t);
要使其正常工作,请删除
Object object = session.merge(t);
from update method of your DAO class. 从您的DAO类的更新方法。 Here is updated update method
这是更新的更新方法
@Override
public void update(T t) throws DaoException {
session.saveOrUpdate(t);
log.info("Update: " + t);
}
This will fix your org.hibernate.id.IdentifierGenerationException
exception. 这将修复您的
org.hibernate.id.IdentifierGenerationException
异常。
Here is a good example of One-To-One association mapping 这是一对一关联映射的一个好例子
I solved my poroblem. 我解决了麻烦。 In my BaseDao and BaseService I removed:
在我的BaseDao和BaseService中,我删除了:
private Session session = HibernateUtil.getHibernateUtil().getSession();
And I added in all methods in BaseDao and BaseService: 我在BaseDao和BaseService中添加了所有方法:
HibernateUtil.getHibernateUtil().getSession();
so I removed the two sessions and my method, example create, became: 所以我删除了两个会话,然后我的方法(例如创建)变成了:
@Override
public void create(T t) throws DaoException {
HibernateUtil.getHibernateUtil().getSession().save(t);
log.info("Create: " + t);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.