Java 为什么我的实体在JPA中保持分离状态?

Java 为什么我的实体在JPA中保持分离状态?,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我正在使用Spring、JPA和Hibernate。这是一个玩具示例,我正在使用它调试一个更大的JPA相关问题。然而,这个试图持久化一个非常基本的实体的简单示例,HelloBean,似乎创建了分离的对象。据我所知,在EntityManager对象上调用persist应该设置要由持久性上下文管理的实体。但是,它不起作用,merge也不起作用。输出如下所示: 正在启动。。。 在上下文中找到的服务为:net.solasistim.hello。HelloService@3b7a687b 休眠:插入Hel

我正在使用Spring、JPA和Hibernate。这是一个玩具示例,我正在使用它调试一个更大的JPA相关问题。然而,这个试图持久化一个非常基本的实体的简单示例,
HelloBean
,似乎创建了分离的对象。据我所知,在
EntityManager
对象上调用
persist
应该设置要由持久性上下文管理的实体。但是,它不起作用,
merge
也不起作用。输出如下所示:

正在启动。。。
在上下文中找到的服务为:net.solasistim.hello。HelloService@3b7a687b
休眠:插入HelloBean(消息)值(?)
bean是否已连接?=假的
休眠:从HelloBean HelloBean 0选择HelloBean 0.id作为id1\u 0\u,从HelloBean HelloBean 0选择HelloBean 0.id作为message2\u 0\u,其中HelloBean 0\u.id=?
bean是否已连接?=假的
为简洁起见,省略了导入

Hello.java
::

公共类你好{
公共静态void main(字符串[]args)引发异常{
ApplicationContext上下文=
新的ClassPathXmlApplicationContext(“beans.xml”);
System.out.println(“开始…”);
HelloService svc=(HelloService)context.getBean(“HelloService”);
System.out.println(“在上下文中找到的服务为:“+svc”);
HelloBean bean1=新HelloBean();
setMessage(“这是bean 1”);
HelloBean bean2=新HelloBean();
setMessage(“这是bean 2”);
svc.persist(bean2);
System.out.println(“是否连接了bean?=”+svc.isAttached(bean2));
HelloBean-newBean=svc.merge(bean2);
System.out.println(“是否连接了bean?=”+svc.isAttached(newBean));
}
}
HelloService.java
::

@服务
@交易的
公共类HelloService{
@PersistenceContext私有实体管理器em;
public void persist(HelloBean实体){
em.persist(实体);
}
公共HelloBean合并(HelloBean实体){
返回em.merge(实体);
}
公共作废删除(HelloBean实体){
em.remove(实体);
}
公共布尔值已附加(HelloBean实体){
返回em.contains(实体);
}
}
HelloBean.java
::

@实体
公共类HelloBean{
@身份证
@生成值
私人长id;
私有字符串消息;
公共无效设置消息(字符串消息){
this.message=消息;
}
公共字符串getMessage(){
返回此消息;
}
}
pom.xml
::


4.0.0
你好
你好
1.
罐子
UTF-8
朱尼特
朱尼特
4.11
测试
org.springframework
spring上下文
3.2.2.1发布
org.springframework
春季甲虫
3.2.2.1发布
org.hibernate
冬眠核心
4.2.0.4最终版本
org.hibernate
休眠实体管理器
4.2.0.4最终版本
mysql
mysql连接器java
5.1.24
beans.xml
::


persistence.xml
::


org.hibernate.ejb.HibernatePersistence

尽管您的
HelloService
是事务性的,但一旦服务的方法返回,事务就会提交。这就是为什么不再在
Hello#main
中管理实体的原因

尝试将输出语句添加到
HelloService
的方法中,您将看到实体附加在这些方法中

编辑:在服务层通常需要事务性。在交易中做每件事很少是明智的。注释
main
方法不是一个好主意,因为只有在main方法返回后,即应用程序终止后,才会刷新持久性上下文

您可以在事务性服务方法中对所连接的实体(您现在可能正在
main
中执行的操作)执行任何需要的操作,就像
HelloService
中的操作一样。此方法可以直接使用
EntityManager
,也可以通过DAO使用。您可以使用
@Transactional(propagation=propagation.MANDATORY)
注释DAO的方法,以确保事务(由服务启动)可用


在其他层(如UI)中处理分离的实体很少有问题。如果分离的实体在服务层之上的层中发生了更改,则需要在以后合并它。如果数据库中的实体可能已更改,则需要重新蚀刻/刷新它

我明白了,它确实附加在服务方法中。我需要以某种方式扩大交易范围。我试图用@Transactional注释main方法——并将其从服务中删除——但行为是一样的,只是实际上没有任何内容被持久化。。。我怎样才能获得更大的事务范围,并且仍然可以进行持久性工作?@amoe已经添加了一些关于事务性的信息,希望能有所帮助。谢谢——现在我明白了。最初的问题需要删除实体,这在分离的实体上失败。因此,有效的解决方案是向服务添加一个
deleteByID
方法,该方法检索并删除同一事务中的实体。