blob: c8a1e3cefe5cfd7243bde47e2cc8fc3f16140a35 [file] [log] [blame]
/*
* Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 IBM Corporation. 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:
// IBM - initial drop
// 05/06/2019 - Jody Grassel
// - 547023 : Add LOB Locator support for core Oracle platform.
package org.eclipse.persistence.jpa.test.oraclefeatures;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.jpa.test.framework.DDLGen;
import org.eclipse.persistence.jpa.test.framework.Emf;
import org.eclipse.persistence.jpa.test.framework.EmfRunner;
import org.eclipse.persistence.jpa.test.framework.Property;
import org.eclipse.persistence.jpa.test.oraclefeatures.model.OracleLobEntity;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.platform.database.OraclePlatform;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EmfRunner.class)
public class TestOracleLOBLocatorFeature {
private final static char[] alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghikjlmnopqrstuvwxyz".toCharArray();
private final static int alphaLen = alphabet.length;
@Emf(name = "emfWithSessionCustomizer",createTables = DDLGen.DROP_CREATE, classes = { OracleLobEntity.class }, properties = {
@Property(name = "eclipselink.session.customizer", value="org.eclipse.persistence.jpa.test.oraclefeatures.OracleLOBLocatorSessionCustomizer")
// @Property(name = "eclipselink.logging.level", value = "FINEST"),
})
private EntityManagerFactory emf;
@Emf(name = "emfNoSessionCustomizer", createTables = DDLGen.DROP_CREATE, classes = { OracleLobEntity.class })
private EntityManagerFactory emfNoSessionCustomizer;
private SecureRandom sr = new SecureRandom();
@Test
public void testOracleLOBLocator() throws Exception {
if (!checkIsOracle()) {
// Skip if not testing against Oracle
return;
}
System.out.println("***** Begin testOracleLOBLocator");
EntityManager em = emf.createEntityManager();
try {
OracleLobEntity blobEntity = new OracleLobEntity();
blobEntity.setStrData("Some Data");
int datalen = 50000;
byte[] data = new byte[datalen];
sr.nextBytes(data);
blobEntity.setBlobData(data);
char[] cdata = new char[datalen];
for (int i = 0; i < datalen; i++) {
cdata[i] = alphabet[Math.abs((sr.nextInt() % alphaLen))];
}
blobEntity.setClobData(new String(cdata));
em.getTransaction().begin();
em.persist(blobEntity);
em.getTransaction().commit();
em.clear();
OracleLobEntity findEntity = em.find(OracleLobEntity.class, blobEntity.getId());
Assert.assertNotNull(findEntity);
Assert.assertEquals(blobEntity.getStrData(), findEntity.getStrData());
Assert.assertEquals(blobEntity.getBlobData(), findEntity.getBlobData());
Assert.assertEquals(blobEntity.getClobData(), findEntity.getClobData());
} finally {
if(em != null) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
System.out.println("***** End testOracleLOBLocator");
}
}
@Test
public void testOracleLOBLocatorWithEmptyClob() throws Exception {
if (!checkIsOracle()) {
// Skip if not testing against Oracle
return;
}
System.out.println("***** Begin testOracleLOBLocatorWithEmptyClob");
EntityManager em = emf.createEntityManager();
try {
OracleLobEntity blobEntity = new OracleLobEntity();
blobEntity.setStrData("Some Data");
int datalen = 50000;
byte[] data = new byte[datalen];
sr.nextBytes(data);
blobEntity.setBlobData(data);
blobEntity.setClobData("");
em.getTransaction().begin();
em.persist(blobEntity);
em.getTransaction().commit();
em.clear();
OracleLobEntity findEntity = em.find(OracleLobEntity.class, blobEntity.getId());
Assert.assertNotNull(findEntity);
Assert.assertEquals(blobEntity.getStrData(), findEntity.getStrData());
Assert.assertEquals(blobEntity.getBlobData(), findEntity.getBlobData());
Assert.assertEquals(blobEntity.getClobData(), findEntity.getClobData());
} finally {
if(em != null) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
System.out.println("***** End testOracleLOBLocatorWithEmptyClob");
}
}
@Test
public void testOracleWithoutLOBLocatorWithEmptyClob() throws Exception {
// After Oracle 11, the lob locator is disabled by default (requiring a Session Customizer to reenable it)
// So the test should fail because Eclipselink will try store a null value instead of an empty_blob()/empty_clob()
// and violate the NOT NULL constraint.
Set<String> notAllowedPlatforms = new HashSet<String>();
notAllowedPlatforms.add("org.eclipse.persistence.platform.database.Oracle8Platform");
notAllowedPlatforms.add("org.eclipse.persistence.platform.database.Oracle9Platform");
notAllowedPlatforms.add("org.eclipse.persistence.platform.database.Oracle10Platform");
if (!checkIsOracle() || notAllowedPlatforms.contains(getPlatform(emfNoSessionCustomizer).getClass().getName())) {
// Skip if not testing against Oracle
return;
}
System.out.println("***** Begin testOracleWithoutLOBLocatorWithEmptyClob");
EntityManager em = emfNoSessionCustomizer.createEntityManager();
try {
OracleLobEntity blobEntity = new OracleLobEntity();
blobEntity.setStrData("Some Data");
int datalen = 50000;
byte[] data = new byte[datalen];
sr.nextBytes(data);
blobEntity.setBlobData(data);
blobEntity.setClobData("");
try {
em.getTransaction().begin();
em.persist(blobEntity);
em.getTransaction().commit();
} catch (jakarta.persistence.RollbackException re) {
// Expected
MatcherAssert.assertThat(re, getExceptionChainMatcher(java.sql.SQLIntegrityConstraintViolationException.class));
}
} finally {
if(em != null) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
System.out.println("***** End testOracleWithoutLOBLocatorWithEmptyClob");
}
}
private boolean checkIsOracle() {
return (emf != null && getPlatform(emf) instanceof OraclePlatform);
}
private DatabasePlatform getPlatform(EntityManagerFactory emf) {
DatabasePlatform platform = ((EntityManagerFactoryImpl) emf).getServerSession().getPlatform();
return platform;
}
@SuppressWarnings("rawtypes")
protected Matcher getExceptionChainMatcher(final Class t) {
return new BaseMatcher() {
final protected Class<?> expected = t;
@Override
public boolean matches(Object obj) {
if (obj == null) {
return (expected == null);
}
if (!(obj instanceof Throwable)) {
return false;
}
final ArrayList<Throwable> tList = new ArrayList<Throwable>();
Throwable t = (Throwable) obj;
while (t != null) {
tList.add(t);
if (expected.equals(t.getClass())) {
return true;
}
if (expected.isAssignableFrom(t.getClass())) {
return true;
}
t = t.getCause();
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(expected.toString());
}
};
}
}