【发布时间】:2018-01-20 16:17:31
【问题描述】:
我正在使用上述库并希望保留一个简单的对象,该对象与另一个对象具有一对一的关系,但不保留关联的对象。这听起来很简单,因为它应该是默认行为。但是,就我而言,出于某种原因,它似乎不是。
我正在使用通过此代码配置的 entityManager:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, Environment env) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setDataSource(dataSource);
return factory;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
这是我的实体类:
@Entity
@Table(name = "`Table_A`", schema = "public")
public class ClassA {
@Id
@Column(name = "a_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "value")
private String value;
@Column(name = "time")
private LocalDateTime time;
@OneToOne(targetEntity = ClassB.class, fetch = FetchType.EAGER)
@JoinColumn(nullable = false, name = "b_id_ref")
private ClassB b;
// getters and setters
}
@Entity
@Table(name = "`Table_B`", schema = "public")
public class ClassB {
@Id
@Column(name = "b_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "value")
private String value;
// getters and setters
}
我不希望 b 在 ClassA 引用的对象被持久化。但是,如果我在 ClassA 的实例中更改 value 并在 ClassB 的相应实例中更改 value。我写了一个小测试来演示程序流程:
@Autowired
private ClassARepository repository;
@PersistenceContext
private EntityManager em;
@Test
public void testCascading() {
Session hibernateSession = em.unwrap(Session.class);
String newValueA = "Sissi";
String newValueB = "Franzl";
ClassA a = createTestInstance();
ClassB b = a.getB();
String oldValueA = token.getTokenValue();
String oldValueB = user.getFirstname();
a.setValue(newValueA);
b.setValue(newValueB);
repository.save(a);
em.flush();
hibernateSession.evict(a);
hibernateSession.evict(b);
ClassA loadedA = repository.findById(1L);
assertThat(loadedA.getB().getValue(), equalTo(oldValueB));
assertThat(loadedA.getValue(), equalTo(newValueA));
}
我检查了“现实世界”中的行为是否相同。正如here 所说,save-操作不应级联。我必须在这里错过一些东西。是否有可能改变默认行为的全局设置?我可以做些什么来实现所需的行为?
【问题讨论】:
-
您的测试是事务性的,对吗?因此,您将获得一个 managed B,并更改其中一个字段的值。所以改变是持久的。您对 save() 和 flush() 的调用是无用的。 JPA 的全部意义在于,当实体被管理 时,它们的状态会自动 持久化。这是一项功能,而不是错误。
-
啊,我明白了。事实上,测试是事务性的,我用来测试行为的“真实世界”方法也是如此。愚蠢的我,我应该有足够的经验不会犯那个错误^^。我很乐意接受你的评论作为答案,如果你做出来的话。