package org.hibernate.bugs;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* This template demonstrates how to develop a test case for Hibernate ORM, using the Java Persistence API.
*/
public class JPAUnitTestCase {
private EntityManagerFactory entityManagerFactory;
private Logger sqlLogger;
private Level initialSqlLevel;
@Before
public void init() {
sqlLogger = Logger.getLogger("org.hibernate.SQL");
initialSqlLevel = sqlLogger.getLevel();
sqlLogger.setLevel(Level.DEBUG);
entityManagerFactory = Persistence.createEntityManagerFactory("templatePU");
}
@After
public void destroy() {
entityManagerFactory.close();
sqlLogger.setLevel(initialSqlLevel);
}
@Test
public void hhh123Test() throws Exception {
EntityManager entityManager = entityManagerFactory.createEntityManager();
int numberOfParents = 5;
runInTransaction(entityManager, () -> {
for (int id = 0; id < numberOfParents; id++) {
Parent parent = new Parent(id);
new Child(id + 100, parent);
entityManager.persist(parent);
}
});
runInTransaction(entityManager, () -> {
RecordingLog4jAppender appender = new RecordingLog4jAppender();
sqlLogger.addAppender(appender);
Query query = entityManager.createQuery("from " + Parent.class.getSimpleName());
@SuppressWarnings("unchecked")
List<Parent> parents = query.getResultList();
sqlLogger.removeAppender(appender);
assertThat(parents).hasSize(numberOfParents);
assertThat(appender.getLogEvents()).size().isLessThan(numberOfParents);
});
entityManager.close();
}
private void runInTransaction(EntityManager entityManager, Runnable runnable) {
entityManager.getTransaction().begin();
runnable.run();
entityManager.getTransaction().commit();
entityManager.clear();
}
}
@Entity
class Parent {
@Id
private long id;
@OneToOne(mappedBy = "parent", optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Child child;
Parent() {}
public Parent(long id) {
this.id = id;
}
void setChild(Child child) {
this.child = child;
}
@Override
public String toString() {
return "Parent [id=" + id + ", child=" + child + "]";
}
}
@Entity
class Child {
@Id
private long id;
@OneToOne(optional = false, fetch = FetchType.LAZY)
private Parent parent;
Child() {}
public Child(long id, Parent parent) {
this.id = id;
setParent(parent);
}
public void setParent(Parent parent) {
this.parent = parent;
parent.setChild(this);
}
@Override
public String toString() {
return "Child [id=" + id + "]";
}
}
class RecordingLog4jAppender extends AppenderSkeleton {
private final List<LoggingEvent> logEvents = new ArrayList<>();
private boolean active = true;
@Override
public boolean requiresLayout() {
return false;
}
@Override
protected void append(LoggingEvent loggingEvent) {
if (active) {
logEvents.add(loggingEvent);
}
}
@Override
public void close() {}
public void setActive(boolean value) {
active = value;
}
public void clear() {
logEvents.clear();
}
public List<LoggingEvent> getLogEvents() {
return Collections.unmodifiableList(logEvents);
}
}