/*
* Copyright 2002-2018 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
*
* https://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;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
Base class for any class that needs to access a JPA EntityManagerFactory
, usually in order to obtain a JPA EntityManager
. Defines common properties. Author: Juergen Hoeller See Also: Since: 2.0
/**
* Base class for any class that needs to access a JPA {@link EntityManagerFactory},
* usually in order to obtain a JPA {@link EntityManager}. Defines common properties.
*
* @author Juergen Hoeller
* @since 2.0
* @see EntityManagerFactoryUtils
*/
public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
Logger available to subclasses. /** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private EntityManagerFactory entityManagerFactory;
@Nullable
private String persistenceUnitName;
private final Map<String, Object> jpaPropertyMap = new HashMap<>();
Set the JPA EntityManagerFactory that should be used to create
EntityManagers.
See Also: - createEntityManager.createEntityManager()
- createEntityManager.createEntityManager(Map)
/**
* Set the JPA EntityManagerFactory that should be used to create
* EntityManagers.
* @see javax.persistence.EntityManagerFactory#createEntityManager()
* @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
*/
public void setEntityManagerFactory(@Nullable EntityManagerFactory emf) {
this.entityManagerFactory = emf;
}
Return the JPA EntityManagerFactory that should be used to create
EntityManagers.
/**
* Return the JPA EntityManagerFactory that should be used to create
* EntityManagers.
*/
@Nullable
public EntityManagerFactory getEntityManagerFactory() {
return this.entityManagerFactory;
}
Obtain the EntityManagerFactory for actual use.
Throws: - IllegalStateException – in case of no EntityManagerFactory set
Returns: the EntityManagerFactory (never null
) Since: 5.0
/**
* Obtain the EntityManagerFactory for actual use.
* @return the EntityManagerFactory (never {@code null})
* @throws IllegalStateException in case of no EntityManagerFactory set
* @since 5.0
*/
protected final EntityManagerFactory obtainEntityManagerFactory() {
EntityManagerFactory emf = getEntityManagerFactory();
Assert.state(emf != null, "No EntityManagerFactory set");
return emf;
}
Set the name of the persistence unit to access the EntityManagerFactory for.
This is an alternative to specifying the EntityManagerFactory by direct reference,
resolving it by its persistence unit name instead. If no EntityManagerFactory and
no persistence unit name have been specified, a default EntityManagerFactory will
be retrieved through finding a single unique bean of type EntityManagerFactory.
See Also: - setEntityManagerFactory
/**
* Set the name of the persistence unit to access the EntityManagerFactory for.
* <p>This is an alternative to specifying the EntityManagerFactory by direct reference,
* resolving it by its persistence unit name instead. If no EntityManagerFactory and
* no persistence unit name have been specified, a default EntityManagerFactory will
* be retrieved through finding a single unique bean of type EntityManagerFactory.
* @see #setEntityManagerFactory
*/
public void setPersistenceUnitName(@Nullable String persistenceUnitName) {
this.persistenceUnitName = persistenceUnitName;
}
Return the name of the persistence unit to access the EntityManagerFactory for, if any.
/**
* Return the name of the persistence unit to access the EntityManagerFactory for, if any.
*/
@Nullable
public String getPersistenceUnitName() {
return this.persistenceUnitName;
}
Specify JPA properties, to be passed into EntityManagerFactory.createEntityManager(Map)
(if any). Can be populated with a String "value" (parsed via PropertiesEditor)
or a "props" element in XML bean definitions.
See Also: - createEntityManager.createEntityManager(Map)
/**
* Specify JPA properties, to be passed into
* {@code EntityManagerFactory.createEntityManager(Map)} (if any).
* <p>Can be populated with a String "value" (parsed via PropertiesEditor)
* or a "props" element in XML bean definitions.
* @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
*/
public void setJpaProperties(Properties jpaProperties) {
CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap);
}
Specify JPA properties as a Map, to be passed into EntityManagerFactory.createEntityManager(Map)
(if any). Can be populated with a "map" or "props" element in XML bean definitions.
See Also: - createEntityManager.createEntityManager(Map)
/**
* Specify JPA properties as a Map, to be passed into
* {@code EntityManagerFactory.createEntityManager(Map)} (if any).
* <p>Can be populated with a "map" or "props" element in XML bean definitions.
* @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
*/
public void setJpaPropertyMap(@Nullable Map<String, Object> jpaProperties) {
if (jpaProperties != null) {
this.jpaPropertyMap.putAll(jpaProperties);
}
}
Allow Map access to the JPA properties to be passed to the persistence
provider, with the option to add or override specific entries.
Useful for specifying entries directly, for example via "jpaPropertyMap[myKey]".
/**
* Allow Map access to the JPA properties to be passed to the persistence
* provider, with the option to add or override specific entries.
* <p>Useful for specifying entries directly, for example via "jpaPropertyMap[myKey]".
*/
public Map<String, Object> getJpaPropertyMap() {
return this.jpaPropertyMap;
}
Retrieves an EntityManagerFactory by persistence unit name, if none set explicitly.
Falls back to a default EntityManagerFactory bean if no persistence unit specified.
See Also: - setPersistenceUnitName
/**
* Retrieves an EntityManagerFactory by persistence unit name, if none set explicitly.
* Falls back to a default EntityManagerFactory bean if no persistence unit specified.
* @see #setPersistenceUnitName
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (getEntityManagerFactory() == null) {
if (!(beanFactory instanceof ListableBeanFactory)) {
throw new IllegalStateException("Cannot retrieve EntityManagerFactory by persistence unit name " +
"in a non-listable BeanFactory: " + beanFactory);
}
ListableBeanFactory lbf = (ListableBeanFactory) beanFactory;
setEntityManagerFactory(EntityManagerFactoryUtils.findEntityManagerFactory(lbf, getPersistenceUnitName()));
}
}
Obtain a new EntityManager from this accessor's EntityManagerFactory.
Can be overridden in subclasses to create specific EntityManager variants.
Throws: - IllegalStateException – if this accessor is not configured with an EntityManagerFactory
See Also: - createEntityManager.createEntityManager()
- createEntityManager.createEntityManager(Map)
Returns: a new EntityManager
/**
* Obtain a new EntityManager from this accessor's EntityManagerFactory.
* <p>Can be overridden in subclasses to create specific EntityManager variants.
* @return a new EntityManager
* @throws IllegalStateException if this accessor is not configured with an EntityManagerFactory
* @see javax.persistence.EntityManagerFactory#createEntityManager()
* @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
*/
protected EntityManager createEntityManager() throws IllegalStateException {
EntityManagerFactory emf = obtainEntityManagerFactory();
Map<String, Object> properties = getJpaPropertyMap();
return (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager());
}
Obtain the transactional EntityManager for this accessor's EntityManagerFactory, if any.
Throws: - IllegalStateException – if this accessor is not configured with an EntityManagerFactory
See Also: - EntityManagerFactoryUtils.getTransactionalEntityManager(EntityManagerFactory)
- EntityManagerFactoryUtils.getTransactionalEntityManager(EntityManagerFactory, Map)
Returns: the transactional EntityManager, or null
if none
/**
* Obtain the transactional EntityManager for this accessor's EntityManagerFactory, if any.
* @return the transactional EntityManager, or {@code null} if none
* @throws IllegalStateException if this accessor is not configured with an EntityManagerFactory
* @see EntityManagerFactoryUtils#getTransactionalEntityManager(javax.persistence.EntityManagerFactory)
* @see EntityManagerFactoryUtils#getTransactionalEntityManager(javax.persistence.EntityManagerFactory, java.util.Map)
*/
@Nullable
protected EntityManager getTransactionalEntityManager() throws IllegalStateException{
EntityManagerFactory emf = obtainEntityManagerFactory();
return EntityManagerFactoryUtils.getTransactionalEntityManager(emf, getJpaPropertyMap());
}
}