/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.collection.delayedOperation;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import javax.persistence.Table;
import org.hibernate.Hibernate;
import org.hibernate.LazyInitializationException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
public class ListAddTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Quizz.class, Question.class };
}
@Before
public void before() {
Session session = sessionFactory().openSession();
Transaction transaction = session.beginTransaction();
try {
Quizz quizz = new Quizz( 1 );
session.persist( quizz );
quizz.addQuestion( new Question( 1, "question 1" ) );
quizz.addQuestion( new Question( 2, "question 2" ) );
quizz.addQuestion( new Question( 3, "question 3" ) );
transaction.commit();
}
finally {
session.close();
}
}
@After
public void after() {
Session session = sessionFactory().openSession();
Transaction transaction = session.beginTransaction();
session.createQuery( "delete Question" ).executeUpdate();
session.createQuery( "delete Quizz" ).executeUpdate();
transaction.commit();
session.close();
}
/**
* This test fails, but shouldn't
*/
@Test
public void addQuestionWithIndexShouldAddQuestionAtSpecifiedIndex() {
Session session = openSession();
Transaction transaction = session.beginTransaction();
Quizz quizz = session.get( Quizz.class, 1 );
quizz.addQuestion( 1, new Question( 4, "question that should be at index 1" ) );
transaction.commit();
session.close();
session = openSession();
transaction = session.beginTransaction();
quizz = session.get( Quizz.class, 1);
assertEquals( 4, quizz.getQuestions().size() );
assertEquals( 4, quizz.getQuestions().get( 1 ).getId().longValue() );
transaction.commit();
session.close();
}
@Test
public void addQuestionToDetachedQuizz() {
Session session = openSession();
session.beginTransaction();
Quizz quizz = session.get( Quizz.class, 1 );
session.getTransaction().commit();
session.close();
assertFalse( ( (PersistentCollection) quizz.getQuestions() ).wasInitialized() );
try {
// this is the crux of the comment on HHH-9195 in regard to uninitialized, detached collections and
// not allowing additions
quizz.addQuestion( new Question( 4, "question 4" ) );
// indexed-addition should fail
quizz.addQuestion( 1, new Question( 5, "question that should be at index 1" ) );
fail( "Expecting a failure" );
}
catch (LazyInitializationException ignore) {
// expected
}
// session = openSession();
// session.beginTransaction();
// session.merge( quizz );
// session.getTransaction().commit();
// session.close();
//
// session = openSession();
// session.getTransaction().begin();
// quizz = session.get( Quizz.class, 1);
// assertEquals( 5, quizz.getQuestions().size() );
// assertEquals( 5, quizz.getQuestions().get( 1 ).getId().longValue() );
// session.getTransaction().commit();
// session.close();
}
/**
* This test succeeds thanks to a dirty workaround consisting in initializing the ordered question list after the
* question has been inserted
*/
@Test
public void addQuestionWithIndexAndInitializeTheListShouldAddQuestionAtSpecifiedIndex() {
Session session = openSession();
Transaction transaction = session.beginTransaction();
Quizz quizz = session.get( Quizz.class, 1 );
quizz.addQuestionAndInitializeLazyList( 1, new Question( 4, "question that should be at index 1" ) );
transaction.commit();
session.close();
session = openSession();
transaction = session.beginTransaction();
quizz = session.get( Quizz.class, 1 );
assertEquals( 4, quizz.getQuestions().size());
assertEquals( 4, quizz.getQuestions().get(1).getId().longValue() );
transaction.commit();
session.close();
}
@Test
@TestForIssue( jiraKey = "HHH-10375")
public void testAddQuestionAfterSessionIsClosed(){
Session session = openSession();
Transaction transaction = session.beginTransaction();
Quizz quizz = session.get( Quizz.class, 1 );
assertThat( "expected 3 questions", quizz.getQuestions().size(), is(3) );
transaction.commit();
session.close();
quizz.addQuestion( new Question( 4, "question 4" ) );
assertThat( "expected 4 questions", quizz.getQuestions().size(), is(4) );
quizz.addQuestion( 1, new Question( 5, "question 5" ) );
assertThat( "expected 5 questions", quizz.getQuestions().size(), is(5) );
}
@Entity( name = "Question" )
@Table( name = "Question" )
public static class Question {
@Id
private Integer id;
private String text;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Quizz quizz;
public Question() {
}
public Question(Integer id, String text) {
this.id = id;
this.text = text;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Quizz getQuizz() {
return quizz;
}
public void setQuizz(Quizz quizz) {
this.quizz = quizz;
}
@Override
public String toString() {
return "Question{" +
"id=" + id +
", text='" + text + '\'' +
'}';
}
}
@Entity( name = "Quizz" )
@Table( name = "Quiz" )
public static class Quizz {
@Id
private Integer id;
@OneToMany(mappedBy = "quizz", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "position")
private List<Question> questions = new ArrayList<Question>();
public Quizz() {
}
public Quizz(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Question> getQuestions() {
return questions;
}
public void addQuestion(Question question) {
question.setQuizz(this);
questions.add(question);
}
public void addQuestion(int index, Question question) {
question.setQuizz(this);
questions.add(index, question);
}
public void addQuestionAndInitializeLazyList(int index, Question question) {
question.setQuizz(this);
questions.add(index, question);
Hibernate.initialize( questions );
}
}
}