blob: 5bd07464241003040346c6a629cfad33f6744e98 [file] [log] [blame]
/*
* Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015 SAP. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// SAP - initial API and implementation
package org.eclipse.persistence.testing.tests.wdf.jpa1.relation;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jakarta.persistence.EntityManager;
import javax.sql.DataSource;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Review;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Before;
import org.junit.Test;
@SuppressWarnings("unchecked")
public class TestUnidirectionalOneToMany extends JPA1Base {
private static final int EMP_ID_VALUE = 4;
private static final Integer EMP_ID = EMP_ID_VALUE;
private static final Set<Pair> SEED_SET = new HashSet<Pair>();
static {
SEED_SET.add(new Pair(EMP_ID_VALUE, 1));
SEED_SET.add(new Pair(EMP_ID_VALUE, 2));
SEED_SET.add(new Pair(EMP_ID_VALUE, 3));
}
@Before
public void seedDataModel() throws SQLException {
clearAllTables(); // clear all tables;
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
env.beginTransaction(em);
Department dep = new Department(17, "R&D");
Employee emp = new Employee(EMP_ID_VALUE, "Hans", "Wurst", dep);
Review r1 = new Review(1, Date.valueOf("2005-10-07"), "bla");
Review r2 = new Review(2, Date.valueOf("2005-10-08"), "ble");
Review r3 = new Review(3, Date.valueOf("2005-10-09"), "bli");
emp.addReview(r1);
emp.addReview(r2);
emp.addReview(r3);
em.persist(dep);
em.persist(emp);
em.persist(r1);
em.persist(r2);
em.persist(r3);
env.commitTransactionAndClear(em);
} finally {
closeEntityManager(em);
}
}
@Test
public void testUnchanged() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
// 1. do nothing
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
// do nothing
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(!emp.postUpdateWasCalled(), "postUpdate was called");
checkJoinTable(SEED_SET);
// 2. touch the reviews
env.beginTransaction(em);
emp = em.find(Employee.class, EMP_ID);
emp.getReviews().size();
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(!emp.postUpdateWasCalled(), "postUpdate was called");
checkJoinTable(SEED_SET);
// 3. trivial update
env.beginTransaction(em);
emp = em.find(Employee.class, EMP_ID);
Set<Review> reviews = emp.getReviews();
emp.setReviews(new HashSet<Review>(reviews));
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(!emp.postUpdateWasCalled(), "postUpdate was called");
checkJoinTable(SEED_SET);
} finally {
closeEntityManager(em);
}
}
private void checkJoinTable(Set<Pair> expected) throws SQLException {
DataSource ds = getEnvironment().getDataSource();
Connection conn = ds.getConnection();
try {
PreparedStatement pstmt = conn.prepareStatement("SELECT EMP_ID, REVIEW_ID FROM TMP_EMP_REVIEW");
try {
ResultSet rs = pstmt.executeQuery();
try {
Set<Pair> actual = new HashSet<Pair>();
while (rs.next()) {
actual.add(new Pair(rs.getInt("EMP_ID"), rs.getInt("REVIEW_ID")));
}
verify(expected.size() == actual.size(), "actual set has wrong size " + actual.size() + " expected: "
+ expected.size());
verify(expected.containsAll(actual), "actual set contains some elements missing in the expecetd set");
verify(actual.containsAll(expected), "expected set contains some elements missing in the actual set");
} finally {
rs.close();
}
} finally {
pstmt.close();
}
} finally {
conn.close();
}
}
@Test
public void testDeleteEmployee() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
verify(emp != null, "employee not found");
em.remove(emp);
env.commitTransactionAndClear(em);
checkJoinTable(new HashSet<Pair>());
} finally {
closeEntityManager(em);
}
}
@Test
public void testDeleteReview() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
verify(emp != null, "employee not found");
Set<Review> reviews = emp.getReviews();
verify(reviews != null, "reviews are null");
verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
Iterator<Review> iter = reviews.iterator();
Review review = iter.next();
int removedId = review.getId();
// there are no managed relationships -> we have to remove the reviews on both sides
em.remove(review);
iter.remove();
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(emp.postUpdateWasCalled(), "post update was not called");
Set<Pair> expected = new HashSet<Pair>(SEED_SET);
expected.remove(new Pair(EMP_ID_VALUE, removedId));
checkJoinTable(expected);
env.beginTransaction(em);
emp = em.find(Employee.class, EMP_ID);
reviews = emp.getReviews();
verify(reviews.size() == 2, "not exactly 2 reviews but " + reviews.size());
Object object = em.find(Review.class, removedId);
verify(object == null, "review found");
env.rollbackTransactionAndClear(em);
} finally {
closeEntityManager(em);
}
}
@Test
public void testAdd() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
verify(emp != null, "employee not found");
Set<Review> reviews = emp.getReviews();
Review r4 = new Review(4, Date.valueOf("2005-10-10"), "blo");
em.persist(r4);
reviews.add(r4);
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(emp.postUpdateWasCalled(), "post update was not called");
Set<Pair> expected = new HashSet<Pair>(SEED_SET);
expected.add(new Pair(EMP_ID_VALUE, 4));
checkJoinTable(expected);
env.beginTransaction(em);
emp = em.find(Employee.class, EMP_ID);
reviews = emp.getReviews();
verify(reviews.size() == 4, "not exactly 4 reviews but " + reviews.size());
env.rollbackTransactionAndClear(em);
} finally {
closeEntityManager(em);
}
}
@Test
public void testExchange() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
verify(emp != null, "employee not found");
Set<Review> reviews = emp.getReviews();
Iterator<Review> iter = reviews.iterator();
Review review = iter.next();
int removedId = review.getId();
// there are no managed relationships -> we have to remove the reviews on both sides
em.remove(review);
iter.remove();
Review r4 = new Review(4, Date.valueOf("2005-10-10"), "blo");
em.persist(r4);
reviews.add(r4);
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(emp.postUpdateWasCalled(), "post update was not called");
Set<Pair> expected = new HashSet<Pair>(SEED_SET);
expected.remove(new Pair(EMP_ID_VALUE, removedId));
expected.add(new Pair(EMP_ID_VALUE, 4));
checkJoinTable(expected);
env.beginTransaction(em);
emp = em.find(Employee.class, EMP_ID);
reviews = emp.getReviews();
verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
env.rollbackTransactionAndClear(em);
} finally {
closeEntityManager(em);
}
}
@Test
public void testMoveAllReviews() throws SQLException {
JPAEnvironment env = getEnvironment();
EntityManager em = env.getEntityManager();
try {
final int newId = 15;
env.beginTransaction(em);
Employee emp = em.find(Employee.class, EMP_ID);
verify(emp != null, "employee not found");
Set<Review> reviews = emp.getReviews();
Employee newEmp = new Employee(newId, "Paulchen", "M\u00fcller", null);
newEmp.setReviews(reviews);
emp.setReviews(null);
em.persist(newEmp);
emp.clearPostUpdate();
env.commitTransactionAndClear(em);
verify(emp.postUpdateWasCalled(), "post update was not called");
Set<Pair> expected = new HashSet<Pair>();
expected.add(new Pair(newId, 1));
expected.add(new Pair(newId, 2));
expected.add(new Pair(newId, 3));
checkJoinTable(expected);
env.beginTransaction(em);
emp = em.find(Employee.class, newId);
reviews = emp.getReviews();
verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
env.rollbackTransactionAndClear(em);
} finally {
closeEntityManager(em);
}
}
private static class Pair {
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof Pair) {
Pair other = (Pair) obj;
return other.empId == empId && other.reviewId == reviewId;
}
return false;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return empId + 17 * reviewId;
}
/**
* @return Returns the empId.
*/
@SuppressWarnings("unused")
public int getEmpId() {
return empId;
}
/**
* @return Returns the reviewId.
*/
@SuppressWarnings("unused")
public int getReviewId() {
return reviewId;
}
final int empId;
final int reviewId;
Pair(int e, int r) {
empId = e;
reviewId = r;
}
}
}