package org.hibernate.examples.mapping.associations.manytoone;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.examples.AbstractJpaTest;
import org.junit.Test;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* org.hibernate.examples.mapping.associations.manytoone.ManyToOneTest
*
* @author 배성혁 sunghyouk.bae@gmail.com
* @since 2013. 11. 29. 오전 9:47
*/
@Slf4j
@Transactional
public class ManyToOneTest extends AbstractJpaTest {
@PersistenceContext
EntityManager em;
@Test
@Transactional
public void bidirectionalManyToOneInsertUpdateFalse() throws Exception {
BeerVendor vendor = new BeerVendor();
vendor.setName("Heineken");
em.persist(vendor);
Brewery hoeBrewery = new Brewery();
Beer hoegaarden = new Beer();
hoeBrewery.getBeers().add(hoegaarden);
hoegaarden.setBrewery(hoeBrewery);
hoeBrewery.setVendor(vendor);
em.persist(hoeBrewery);
em.flush();
em.clear();
hoegaarden = em.find(Beer.class, hoegaarden.getId());
assertThat(hoegaarden).isNotNull();
// load ManyToOne
assertThat(hoegaarden.getBrewery()).isNotNull();
assertThat(hoegaarden.getBrewery().getId()).isNotNull();
assertThat(hoegaarden.getBrewery().getBeers()).hasSize(1).containsOnly(hoegaarden);
assertThat(hoegaarden.getBrewery().getVendor()).isNotNull();
assertThat(hoegaarden.getBrewery().getVendor().getId()).isNotNull();
// citron을 명시적으로 저장하지 않은 것은, Brewery#beers @OneToMany에 mappedBy 를 지정하지 않았기 때문에 전체를 한번에 추가 삭제합니다.
// 만약 Brewery#beers에 mappedBy="brewery" 를 추가한다면, Beer 엔티티 개별로 조작해야 하므로, citron은 미리 저장해야 합니다.
// 또한 Beer#brewery의 cascadeType도 MERGE|PERSIST|REFRESH 를 추가해야 합니다.
Beer citron = new Beer();
hoeBrewery = hoegaarden.getBrewery();
hoeBrewery.getBeers().remove(hoegaarden);
hoeBrewery.getBeers().add(citron);
citron.setBrewery(hoeBrewery);
// ManyToOne 의 cascadeType 에 CascadeType.PERSIST 가 있으므로, hoeBrewery도 update 된다.
em.remove(hoegaarden);
em.flush();
em.clear();
citron = em.find(Beer.class, citron.getId());
assertThat(citron.getBrewery().getBeers()).hasSize(1).containsOnly(citron);
hoeBrewery = citron.getBrewery();
citron.setBrewery(null);
hoeBrewery.getBeers().clear();
em.remove(citron);
em.remove(hoeBrewery);
em.flush();
}
@Test
public void uniDirectionalManyToOne() {
Jug jug = new Jug("JUG Summer Camp");
JugMember emmanuel = new JugMember("Emmanuel Bernard");
emmanuel.setMemberOf(jug);
JugMember jerome = new JugMember("Jerome");
jerome.setMemberOf(jug);
em.persist(jug);
em.persist(emmanuel);
em.persist(jerome);
em.flush();
em.clear();
emmanuel = em.find(JugMember.class, emmanuel.getId());
assertThat(emmanuel).isNotNull();
assertThat(emmanuel.getMemberOf()).isNotNull();
assertThat(emmanuel.getMemberOf()).isEqualTo(jug);
em.remove(emmanuel);
em.flush();
em.clear();
jerome = em.find(JugMember.class, jerome.getId());
assertThat(jerome.getMemberOf()).isNotNull();
assertThat(jerome.getMemberOf()).isEqualTo(jug);
em.remove(jerome);
em.flush();
em.clear();
jug = em.find(Jug.class, jug.getId());
assertThat(jug).isNotNull();
em.remove(jug);
em.flush();
}
@Test
public void bidirectionalManyToOneRegular() throws Exception {
SalesForce force = new SalesForce("Red Hat");
em.persist(force);
SalesGuy eric = new SalesGuy();
eric.setName("Eric");
eric.setSalesForce(force);
force.getSalesGuys().add(eric);
em.persist(eric);
SalesGuy simon = new SalesGuy();
simon.setName("Simon");
simon.setSalesForce(force);
force.getSalesGuys().add(simon);
em.persist(simon);
em.flush();
em.clear();
force = em.find(SalesForce.class, force.getId());
assertThat(force).isNotNull();
assertThat(force.getSalesGuys()).isNotNull();
assertThat(force.getSalesGuys()).hasSize(2);
for (SalesGuy guy : force.getSalesGuys()) {
assertThat(guy.getId()).isNotNull();
}
simon = em.find(SalesGuy.class, simon.getId());
// Cascade 때문에
force.getSalesGuys().remove(simon);
em.remove(simon);
em.flush();
em.clear();
force = em.find(SalesForce.class, force.getId());
assertThat(force).isNotNull();
assertThat(force.getSalesGuys()).isNotNull();
assertThat(force.getSalesGuys()).hasSize(1);
em.remove(force.getSalesGuys().iterator().next());
em.remove(force);
em.flush();
}
}