Reputation: 1088
I'm using the mentioned libraries and want to persist a simple object, that has a one-to-one-relationship with another, without persisting the associated object. That might sound simple, because it should be the default behaviour. However, in my case for some reason it seems not to be.
I'm using an entityManager configured by this code:
@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;
}
Here are my entity classes:
@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
}
I don't want the object that b
in ClassA
references to be persisted. But if I change value
in an instance of ClassA
and also value
in the corresponding instance of ClassB. I wrote a small test to demonstrate the program flow:
@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));
}
I checked that the bahaviour is the same in the "real world". Like it is stated here the save
-operation should not be cascaded. I must miss something here. Is there maybe a global setting that changes the default behaviour? What can I do to achieve the desired behaviour?
Upvotes: 2
Views: 564
Reputation: 692071
Your test is transactional. So you're getting a managed B, and changing the value of one of its field. And the change is thus made persistent.
Your calls to save()
and flush()
are useless, by the way. The whole point of JPA is that when entities are managed, their state is made persistent automatically. It's a feature, not a bug.
Upvotes: 4