parent
d341624e91
commit
69ec437fbc
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.vendor;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.openjpa.persistence.FetchPlan;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
||||
import org.apache.openjpa.persistence.jdbc.IsolationLevel;
|
||||
import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
|
||||
|
||||
import org.springframework.jdbc.datasource.ConnectionHandle;
|
||||
import org.springframework.jdbc.datasource.ConnectionHolder;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
import org.springframework.orm.jpa.DefaultJpaDialect;
|
||||
import org.springframework.transaction.SavepointManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.orm.jpa.JpaDialect} implementation for Apache OpenJPA.
|
||||
* Developed and tested against OpenJPA 2.2.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @since 2.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class OpenJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
@Override
|
||||
public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition)
|
||||
throws PersistenceException, SQLException, TransactionException {
|
||||
|
||||
OpenJPAEntityManager openJpaEntityManager = getOpenJPAEntityManager(entityManager);
|
||||
|
||||
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
|
||||
// Pass custom isolation level on to OpenJPA's JDBCFetchPlan configuration
|
||||
FetchPlan fetchPlan = openJpaEntityManager.getFetchPlan();
|
||||
if (fetchPlan instanceof JDBCFetchPlan) {
|
||||
IsolationLevel isolation = IsolationLevel.fromConnectionConstant(definition.getIsolationLevel());
|
||||
((JDBCFetchPlan) fetchPlan).setIsolation(isolation);
|
||||
}
|
||||
}
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
|
||||
if (!definition.isReadOnly()) {
|
||||
// Like with EclipseLink, make sure to start the logic transaction early so that other
|
||||
// participants using the connection (such as JdbcTemplate) run in a transaction.
|
||||
openJpaEntityManager.beginStore();
|
||||
}
|
||||
|
||||
// Custom implementation for OpenJPA savepoint handling
|
||||
return new OpenJpaTransactionData(openJpaEntityManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly)
|
||||
throws PersistenceException, SQLException {
|
||||
|
||||
return new OpenJpaConnectionHandle(getOpenJPAEntityManager(entityManager));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the OpenJPA-specific variant of {@code EntityManager}.
|
||||
* @param em the generic {@code EntityManager} instance
|
||||
* @return the OpenJPA-specific variant of {@code EntityManager}
|
||||
*/
|
||||
protected OpenJPAEntityManager getOpenJPAEntityManager(EntityManager em) {
|
||||
return OpenJPAPersistence.cast(em);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transaction data Object exposed from {@code beginTransaction},
|
||||
* implementing the {@link SavepointManager} interface.
|
||||
*/
|
||||
private static class OpenJpaTransactionData implements SavepointManager {
|
||||
|
||||
private final OpenJPAEntityManager entityManager;
|
||||
|
||||
private int savepointCounter = 0;
|
||||
|
||||
public OpenJpaTransactionData(OpenJPAEntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createSavepoint() throws TransactionException {
|
||||
this.savepointCounter++;
|
||||
String savepointName = ConnectionHolder.SAVEPOINT_NAME_PREFIX + this.savepointCounter;
|
||||
this.entityManager.setSavepoint(savepointName);
|
||||
return savepointName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackToSavepoint(Object savepoint) throws TransactionException {
|
||||
this.entityManager.rollbackToSavepoint((String) savepoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSavepoint(Object savepoint) throws TransactionException {
|
||||
try {
|
||||
this.entityManager.releaseSavepoint((String) savepoint);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
LogFactory.getLog(OpenJpaTransactionData.class).debug(
|
||||
"Could not explicitly release OpenJPA savepoint", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link ConnectionHandle} implementation that fetches a new OpenJPA-provided
|
||||
* Connection for every {@code getConnection} call and closes the Connection on
|
||||
* {@code releaseConnection}. This is necessary because OpenJPA requires the
|
||||
* fetched Connection to be closed before continuing EntityManager work.
|
||||
* @see org.apache.openjpa.persistence.OpenJPAEntityManager#getConnection()
|
||||
*/
|
||||
private static class OpenJpaConnectionHandle implements ConnectionHandle {
|
||||
|
||||
private final OpenJPAEntityManager entityManager;
|
||||
|
||||
public OpenJpaConnectionHandle(OpenJPAEntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return (Connection) this.entityManager.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection con) {
|
||||
JdbcUtils.closeConnection(con);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.vendor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.spi.PersistenceProvider;
|
||||
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
|
||||
import org.apache.openjpa.persistence.PersistenceProviderImpl;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Apache OpenJPA.
|
||||
* Developed and tested against OpenJPA 2.2.
|
||||
*
|
||||
* <p>Exposes OpenJPA's persistence provider and EntityManager extension interface,
|
||||
* and adapts {@link AbstractJpaVendorAdapter}'s common configuration settings.
|
||||
* No support for the detection of annotated packages (through
|
||||
* {@link org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo#getManagedPackages()})
|
||||
* since OpenJPA doesn't use package-level metadata.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @since 2.0
|
||||
* @see OpenJpaDialect
|
||||
* @see org.apache.openjpa.persistence.PersistenceProviderImpl
|
||||
* @see org.apache.openjpa.persistence.OpenJPAEntityManager
|
||||
*/
|
||||
public class OpenJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
||||
|
||||
private final PersistenceProvider persistenceProvider = new PersistenceProviderImpl();
|
||||
|
||||
private final OpenJpaDialect jpaDialect = new OpenJpaDialect();
|
||||
|
||||
|
||||
@Override
|
||||
public PersistenceProvider getPersistenceProvider() {
|
||||
return this.persistenceProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPersistenceProviderRootPackage() {
|
||||
return "org.apache.openjpa";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getJpaPropertyMap() {
|
||||
Map<String, Object> jpaProperties = new HashMap<String, Object>();
|
||||
|
||||
if (getDatabasePlatform() != null) {
|
||||
jpaProperties.put("openjpa.jdbc.DBDictionary", getDatabasePlatform());
|
||||
}
|
||||
else if (getDatabase() != null) {
|
||||
String databaseDictonary = determineDatabaseDictionary(getDatabase());
|
||||
if (databaseDictonary != null) {
|
||||
jpaProperties.put("openjpa.jdbc.DBDictionary", databaseDictonary);
|
||||
}
|
||||
}
|
||||
|
||||
if (isGenerateDdl()) {
|
||||
jpaProperties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
|
||||
}
|
||||
if (isShowSql()) {
|
||||
// Taken from the OpenJPA 0.9.6 docs ("Standard OpenJPA Log Configuration + All SQL Statements")
|
||||
jpaProperties.put("openjpa.Log", "DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE");
|
||||
}
|
||||
|
||||
return jpaProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the OpenJPA database dictionary name for the given database.
|
||||
* @param database the specified database
|
||||
* @return the OpenJPA database dictionary name, or {@code null} if none found
|
||||
*/
|
||||
protected String determineDatabaseDictionary(Database database) {
|
||||
switch (database) {
|
||||
case DB2: return "db2";
|
||||
case DERBY: return "derby";
|
||||
case HSQL: return "hsql(SimulateLocking=true)";
|
||||
case INFORMIX: return "informix";
|
||||
case MYSQL: return "mysql";
|
||||
case ORACLE: return "oracle";
|
||||
case POSTGRESQL: return "postgres";
|
||||
case SQL_SERVER: return "sqlserver";
|
||||
case SYBASE: return "sybase";
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenJpaDialect getJpaDialect() {
|
||||
return this.jpaDialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface() {
|
||||
return OpenJPAEntityManagerFactorySPI.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends EntityManager> getEntityManagerInterface() {
|
||||
return OpenJPAEntityManagerSPI.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,20 +36,11 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests extends org.s
|
|||
"/org/springframework/orm/jpa/hibernate/hibernate-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
protected static final String[] OPENJPA_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
|
||||
private static Provider getProvider() {
|
||||
String provider = System.getProperty("org.springframework.orm.jpa.provider");
|
||||
if (provider != null) {
|
||||
if (provider.toLowerCase().contains("hibernate")) {
|
||||
return Provider.HIBERNATE;
|
||||
}
|
||||
if (provider.toLowerCase().contains("openjpa")) {
|
||||
return Provider.OPENJPA;
|
||||
}
|
||||
if (provider != null && provider.toLowerCase().contains("hibernate")) {
|
||||
return Provider.HIBERNATE;
|
||||
}
|
||||
return Provider.ECLIPSELINK;
|
||||
}
|
||||
|
@ -69,8 +60,6 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests extends org.s
|
|||
return ECLIPSELINK_CONFIG_LOCATIONS;
|
||||
case HIBERNATE:
|
||||
return HIBERNATE_CONFIG_LOCATIONS;
|
||||
case OPENJPA:
|
||||
return OPENJPA_CONFIG_LOCATIONS;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown provider: " + provider);
|
||||
}
|
||||
|
@ -92,7 +81,7 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests extends org.s
|
|||
|
||||
static enum Provider {
|
||||
|
||||
ECLIPSELINK, HIBERNATE, OPENJPA
|
||||
ECLIPSELINK, HIBERNATE
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.openjpa;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* OpenJPA-specific JPA tests.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class OpenJpaEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigPaths() {
|
||||
return OPENJPA_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
public void testCanCastNativeEntityManagerFactoryToOpenJpaEntityManagerFactoryImpl() {
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
assertTrue("native EMF expected", emfi.getNativeEntityManagerFactory() instanceof OpenJPAEntityManagerFactory);
|
||||
}
|
||||
|
||||
public void testCanCastSharedEntityManagerProxyToOpenJpaEntityManager() {
|
||||
assertTrue("native EM expected", sharedEntityManager instanceof OpenJPAEntityManager);
|
||||
}
|
||||
|
||||
public void testCanGetSharedOpenJpaEntityManagerProxy() {
|
||||
OpenJPAEntityManager openJPAEntityManager = (OpenJPAEntityManager) SharedEntityManagerCreator.createSharedEntityManager(
|
||||
entityManagerFactory, null, OpenJPAEntityManager.class);
|
||||
assertNotNull(openJPAEntityManager.getDelegate());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSavepoint() {
|
||||
TransactionTemplate tt = new TransactionTemplate(transactionManager);
|
||||
tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
Person tony = new Person();
|
||||
tony.setFirstName("Tony");
|
||||
sharedEntityManager.merge(tony);
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
q.setFlushMode(FlushModeType.COMMIT);
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(1, people.size());
|
||||
assertEquals("Tony", people.get(0).getFirstName());
|
||||
status.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(0, people.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.openjpa;
|
||||
|
||||
/**
|
||||
* Test that AspectJ weaving (in particular the currently shipped aspects) works
|
||||
* with JPA (see SPR-3873 for more details).
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class OpenJpaEntityManagerFactoryWithAspectJWeavingIntegrationTests extends OpenJpaEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String[] getConfigPaths() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager-aspectj-weaving.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue