BAEL-446: Deleting objects with Hibernate. (#879)

This commit is contained in:
Dragan Bozanovic 2016-12-05 22:46:23 +01:00 committed by Zeger Hendrikse
parent 50bc4fb460
commit d0a6a0ed92
7 changed files with 354 additions and 2 deletions

View File

@ -40,7 +40,7 @@ public class PersistenceJPAConfigL2Cache {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
em.setPackagesToScan(getPackagesToScan());
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
@ -49,6 +49,10 @@ public class PersistenceJPAConfigL2Cache {
return em;
}
protected String[] getPackagesToScan() {
return new String[] { "org.baeldung.persistence.model" };
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
@ -78,6 +82,7 @@ public class PersistenceJPAConfigL2Cache {
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
hibernateProperties.setProperty("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
return hibernateProperties;
}

View File

@ -6,7 +6,7 @@ jdbc.user=sa
# hibernate.X
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true

View File

@ -0,0 +1,17 @@
package org.baeldung.persistence.deletion.config;
import org.baeldung.config.PersistenceJPAConfigL2Cache;
import java.util.Properties;
public class PersistenceJPAConfigDeletion extends PersistenceJPAConfigL2Cache {
public PersistenceJPAConfigDeletion() {
super();
}
@Override
protected String[] getPackagesToScan() {
return new String[] { "org.baeldung.persistence.deletion.model" };
}
}

View File

@ -0,0 +1,60 @@
package org.baeldung.persistence.deletion.model;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "BAR")
public class Bar {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false)
private String name;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
List<Baz> bazList = new ArrayList<>();
public Bar() {
super();
}
public Bar(final String name) {
super();
this.name = name;
}
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public List<Baz> getBazList() {
return bazList;
}
public void setBazList(final List<Baz> bazList) {
this.bazList = bazList;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Bar [name=").append(name).append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,48 @@
package org.baeldung.persistence.deletion.model;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "BAZ")
public class Baz {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false)
private String name;
public Baz() {
super();
}
public Baz(final String name) {
super();
this.name = name;
}
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Bar [name=").append(name).append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,63 @@
package org.baeldung.persistence.deletion.model;
import org.hibernate.annotations.Where;
import javax.persistence.*;
@Entity
@Table(name = "FOO")
@Where(clause = "DELETED = 0")
public class Foo {
public Foo() {
super();
}
public Foo(final String name) {
super();
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private long id;
@Column(name = "NAME")
private String name;
@Column(name = "DELETED")
private Integer deleted = 0;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "BAR_ID")
private Bar bar;
public Bar getBar() {
return bar;
}
public void setBar(final Bar bar) {
this.bar = bar;
}
public long getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public void setDeleted() {
this.deleted = 1;
}
}

View File

@ -0,0 +1,159 @@
package org.baeldung.persistence.service;
import org.baeldung.persistence.deletion.config.PersistenceJPAConfigDeletion;
import org.baeldung.persistence.deletion.model.Bar;
import org.baeldung.persistence.deletion.model.Baz;
import org.baeldung.persistence.deletion.model.Foo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceJPAConfigDeletion.class }, loader = AnnotationConfigContextLoader.class)
public class DeletionIntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PlatformTransactionManager platformTransactionManager;
@Before
public final void before() {
entityManager.getEntityManagerFactory().getCache().evictAll();
}
@Test
@Transactional
public final void givenEntityIsRemoved_thenItIsNotInDB() {
Foo foo = new Foo("foo");
entityManager.persist(foo);
flushAndClear();
foo = entityManager.find(Foo.class, foo.getId());
assertThat(foo, notNullValue());
entityManager.remove(foo);
flushAndClear();
assertThat(entityManager.find(Foo.class, foo.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsRemovedAndReferencedByAnotherEntity_thenItIsNotRemoved() {
Bar bar = new Bar("bar");
Foo foo = new Foo("foo");
foo.setBar(bar);
entityManager.persist(foo);
flushAndClear();
foo = entityManager.find(Foo.class, foo.getId());
bar = entityManager.find(Bar.class, bar.getId());
entityManager.remove(bar);
flushAndClear();
bar = entityManager.find(Bar.class, bar.getId());
assertThat(bar, notNullValue());
foo = entityManager.find(Foo.class, foo.getId());
foo.setBar(null);
entityManager.remove(bar);
flushAndClear();
assertThat(entityManager.find(Bar.class, bar.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsRemoved_thenRemovalIsCascaded() {
Bar bar = new Bar("bar");
Foo foo = new Foo("foo");
foo.setBar(bar);
entityManager.persist(foo);
flushAndClear();
foo = entityManager.find(Foo.class, foo.getId());
entityManager.remove(foo);
flushAndClear();
assertThat(entityManager.find(Foo.class, foo.getId()), nullValue());
assertThat(entityManager.find(Bar.class, bar.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsDisassociated_thenOrphanRemovalIsApplied() {
Bar bar = new Bar("bar");
Baz baz = new Baz("baz");
bar.getBazList().add(baz);
entityManager.persist(bar);
flushAndClear();
bar = entityManager.find(Bar.class, bar.getId());
baz = bar.getBazList().get(0);
bar.getBazList().remove(baz);
flushAndClear();
assertThat(entityManager.find(Baz.class, baz.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsDeletedWithJpaBulkDeleteStatement_thenItIsNotInDB() {
Foo foo = new Foo("foo");
entityManager.persist(foo);
flushAndClear();
entityManager.createQuery("delete from Foo where id = :id")
.setParameter("id", foo.getId())
.executeUpdate();
assertThat(entityManager.find(Foo.class, foo.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsDeletedWithNativeQuery_thenItIsNotInDB() {
Foo foo = new Foo("foo");
entityManager.persist(foo);
flushAndClear();
entityManager.createNativeQuery("delete from FOO where ID = :id")
.setParameter("id", foo.getId())
.executeUpdate();
assertThat(entityManager.find(Foo.class, foo.getId()), nullValue());
}
@Test
@Transactional
public final void givenEntityIsSoftDeleted_thenItIsNotReturnedFromQueries() {
Foo foo = new Foo("foo");
entityManager.persist(foo);
flushAndClear();
foo = entityManager.find(Foo.class, foo.getId());
foo.setDeleted();
flushAndClear();
assertThat(entityManager.find(Foo.class, foo.getId()), nullValue());
}
private void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
}