Java 不带惰性字段的休眠克隆实体
我有两个实体:Java 不带惰性字段的休眠克隆实体,java,hibernate,spring-data-jpa,entitymanager,Java,Hibernate,Spring Data Jpa,Entitymanager,我有两个实体: @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "age") private int age;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id")
private Person person;
及
这个人很懒。我加载一个用户并将其分离
@Transactional
@Override
public void run(String... args) {
User user = userService.getOne(1L);
userService.detach(user);
System.out.println(user.getName());
System.out.println(user.getAge());
Person person = user.getPerson();
System.out.println(person.getName());
System.out.println(person.getNumber());
}
但是当我调用user.getPerson()
时,它不会抛出异常。我期望出现异常,因为我分离了实体并尝试调用LAZY字段,但它仍然有效
我想创建一个不带person的用户克隆,并另存为一个新实体
User user = userService.getOne(1L);
userService.detach(user);
user.setId(null)//autogenerate id
但当我保存用户时,人也会克隆。我可以设置为空:
User user = userService.getOne(1L);
userService.detach(user);
user.setId(null);
user.setPerson(null);
但这个人很懒,看起来像个黑客。那么,分离方法的意义是什么呢
编辑:
非常有趣的事情-如果我在调试断点时启动示例应用程序-所有都可以正常工作,但如果我取消选择所有断点,我会在控制台中遇到异常:
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy [com.example.detachexample.User#1] - no Session
如果我理解的话,你是在克隆上调用分离?这个克隆不是普通的用户对象,而是扩展用户对象的代理 您需要首先使用
unproxy
获取原始加载的实体
User olduser = userService.getOne(1L);
User user = org.hibernate.Hibernate.unproxy(olduser);
if (olduser == user) userService.detach(user);
user.setId(null)//autogenerate id
user.getPerson().setId(null); // so you will generate this as well
user.getPerson().setUser(user); // so that it will point to the correct new entity
如果我理解的话,你是在克隆上调用分离?这个克隆不是普通的用户对象,而是扩展用户对象的代理 您需要首先使用
unproxy
获取原始加载的实体
User olduser = userService.getOne(1L);
User user = org.hibernate.Hibernate.unproxy(olduser);
if (olduser == user) userService.detach(user);
user.setId(null)//autogenerate id
user.getPerson().setId(null); // so you will generate this as well
user.getPerson().setUser(user); // so that it will point to the correct new entity
在
detach
点上,似乎实际加载了Person
根据FetchType
文档,这是可能的:
惰性策略是对持久性提供程序运行时的一个提示
首次访问数据时,应延迟获取数据。这个
允许实现急切地获取数据,而延迟
已指定策略提示
因此,查看Hibernate调试日志,很可能会在某个地方加入Person及其字段的选择。似乎在
分离时,Person
实际上已经加载
根据FetchType
文档,这是可能的:
惰性策略是对持久性提供程序运行时的一个提示
首次访问数据时,应延迟获取数据。这个
允许实现急切地获取数据,而延迟
已指定策略提示
因此,请查看Hibernate调试日志,最有可能的情况是,在某个地方会有一个连接到Person及其字段的选择。当您调用detach时,该对象会从会话(如事务)中分离,并且不会保存到数据库,除非您在某个点再次附加它。。。但是它的所有属性都与您的用例相同,您需要在分离“用户”后刷新会话。一旦您准备好“克隆”对象,您将需要一个打开的会话当您调用detach时,该对象将从会话(如事务)中分离,并且不会保存到数据库,除非您在某个点再次附加它。。。但是它的所有属性都与您的用例相同,您需要在分离“用户”后刷新会话。一旦您准备好“克隆”对象,您将需要一个打开的会话是的,我看到了hibernate日志。首先-加载唯一的用户而不加载人员。之后,我调用detach方法。然后,我调用user.getPerson()
。hibernate进行一个新的查询(标准的延迟加载)。但是我不明白如果用户已经分离,它怎么能做到。是的,我看到了hibernate日志。首先-加载唯一的用户而不加载人员。之后,我调用detach方法。然后,我调用user.getPerson()
。hibernate进行一个新的查询(标准的延迟加载)。但我不明白,如果用户已经分离,它怎么能做到这一点。