| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. 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: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.jpa; |
| |
| import jakarta.persistence.EntityManagerFactory; |
| import jakarta.persistence.Query; |
| import org.eclipse.persistence.internal.jpa.*; |
| import org.eclipse.persistence.internal.localization.ExceptionLocalization; |
| import org.eclipse.persistence.jpa.JpaEntityManager; |
| import org.eclipse.persistence.queries.*; |
| import org.eclipse.persistence.sessions.DatabaseSession; |
| import org.eclipse.persistence.sessions.server.Server; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| import org.eclipse.persistence.sessions.broker.SessionBroker; |
| import org.eclipse.persistence.sessions.factories.SessionFactory; |
| import org.eclipse.persistence.queries.FetchGroupTracker; |
| |
| |
| /** |
| * This sample illustrates the JPA helper methods that may be of use |
| * to EclipseLink customers attempting to leverage EclipseLink specific functionality. |
| * |
| * @author dclarke, gpelletie |
| */ |
| public class JpaHelper { |
| |
| private JpaHelper() { |
| } |
| |
| /** |
| * Verify if the JPA provider is EclipseLink. If you are in a container |
| * and not in a transaction this method may incorrectly return false. |
| * It is always more reliable to check isEclipseLink on the EMF or Query. |
| */ |
| public static boolean isEclipseLink(jakarta.persistence.EntityManager em) { |
| return getEntityManager(em) != null; |
| } |
| |
| /** |
| * Verify if the JPA provider is EclipseLink |
| */ |
| public static boolean isEclipseLink(EntityManagerFactory emf) { |
| try { |
| getEntityManagerFactory(emf); |
| } catch (IllegalArgumentException iae) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Verify if the JPA provider is EclipseLink |
| */ |
| public static boolean isEclipseLink(Query query) { |
| return query instanceof JpaQuery; |
| } |
| |
| /** |
| * Determine if the JPA query is a EclipseLink ReportQuery. Useful for |
| * frameworks that want to determine which get_X_Query method they can |
| * safely invoke. |
| */ |
| public static boolean isReportQuery(Query query) { |
| return isEclipseLink(query) && getDatabaseQuery(query).isReportQuery(); |
| } |
| |
| /** |
| * Access the internal EclipseLink query wrapped within the JPA query. A |
| * EclipseLink JPA created from JP QL contains a ReportQuery if multiple |
| * items or a non-entity type is being returned. This method will fail |
| * if a single entity type is being returned as the query is a ReadAllQuery. |
| * |
| * @see JpaHelper#getReadAllQuery |
| */ |
| public static ReportQuery getReportQuery(Query query) { |
| DatabaseQuery dbQuery = getDatabaseQuery(query); |
| if (dbQuery.isReportQuery()) { |
| return (ReportQuery)dbQuery; |
| } |
| |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_report_query" + query.getClass())); |
| } |
| |
| /** |
| * Access the internal EclipseLink query wrapped within the JPA query. |
| */ |
| public static DatabaseQuery getDatabaseQuery(Query query) { |
| if (query instanceof JpaQuery) { |
| return ((JpaQuery)query).getDatabaseQuery(); |
| } |
| |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_query" + query.getClass())); |
| } |
| |
| /** |
| * Access the internal EclipseLink query wrapped within the JPA query. A EclipseLink |
| * JPA created from JP QL only contains a ReadAllQuery if only a single entity |
| * type is being returned. |
| * |
| * A ReadAllQuery is the super class of a ReportQuery so this method will |
| * always work for either a ReportQuery or ReadAllQuery. |
| */ |
| public static ReadAllQuery getReadAllQuery(Query query) { |
| DatabaseQuery dbQuery = getDatabaseQuery(query); |
| if (dbQuery.isReadAllQuery()) { |
| return (ReadAllQuery)dbQuery; |
| } |
| |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_read_all_query" + query.getClass())); |
| } |
| |
| /** |
| * Create a EclipseLink JPA query dynamically given a EclipseLink query. |
| */ |
| public static Query createQuery(DatabaseQuery query, jakarta.persistence.EntityManager em) { |
| return getEntityManager(em).createQuery(query); |
| } |
| |
| /** |
| * Convert a JPA entityManager into a EclipseLink specific one. This will work |
| * both within a JavaSE deployment as well as within a container where the |
| * EntityManager may be wrapped. |
| * |
| * In the case where the container is not in a transaction it may return null |
| * for its delegate. When this happens the only way to access an EntityManager |
| * is to use the EntityManagerFactory to create a temporary one where the |
| * application manage its lifecycle. |
| */ |
| public static JpaEntityManager getEntityManager(jakarta.persistence.EntityManager entityManager) { |
| if (entityManager instanceof JpaEntityManager) { |
| return (JpaEntityManager)entityManager; |
| } |
| |
| if (entityManager.getDelegate() != null) { |
| return getEntityManager((jakarta.persistence.EntityManager)entityManager.getDelegate()); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Given a JPA EntityManagerFactory attempt to cast it to a EclipseLink EMF. |
| * |
| * Although this method currently returns an instance of EntityManagerFactoryImpl, it |
| * is recommended that users cast to JpaEntityManagerFactory. Future versions of EclipseLink will |
| * return that interface from this method instead |
| * |
| * @see JpaEntityManagerFactory |
| * @deprecated |
| */ |
| @Deprecated |
| public static EntityManagerFactoryImpl getEntityManagerFactory(EntityManagerFactoryImpl emf) { |
| return (emf); |
| } |
| |
| /** |
| * Given a JPA EntityManagerFactory attempt to cast it to a EclipseLink EMF. |
| * |
| * @see JpaEntityManagerFactory |
| */ |
| public static JpaEntityManagerFactory getEntityManagerFactory(EntityManagerFactory emf) { |
| if (emf instanceof JpaEntityManagerFactory) { |
| return ((JpaEntityManagerFactory)emf); |
| } |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_helper_invalid_entity_manager_factory", new Object[]{emf.getClass()})); |
| } |
| |
| /** |
| * Given an EntityManager return the EntityManagerFactory that created it. This method must be called |
| * on an open entity manager and will return null if called on a closed entityManager. |
| * |
| * This method will return null for non-EclipseLink EntityManagers. |
| * |
| * @see JpaEntityManagerFactory |
| */ |
| public static JpaEntityManagerFactory getEntityManagerFactory(jakarta.persistence.EntityManager em) { |
| JpaEntityManager entityManager = getEntityManager(em); |
| if (entityManager != null){ |
| if (entityManager.getEntityManagerFactory() != null){ |
| return ((EntityManagerFactoryDelegate)entityManager.getEntityManagerFactory()).getOwner(); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Retrieve the shared database session from the EMF. |
| */ |
| public static DatabaseSession getDatabaseSession(EntityManagerFactory emf) { |
| return getEntityManagerFactory(emf).getDatabaseSession(); |
| } |
| |
| /** |
| * Retrieve the shared server session from the EMF. |
| */ |
| public static Server getServerSession(EntityManagerFactory emf) { |
| return getEntityManagerFactory(emf).getServerSession(); |
| } |
| |
| /** |
| * Retrieve the shared session broker from the EMF. |
| */ |
| public static SessionBroker getSessionBroker(EntityManagerFactory emf) { |
| return getEntityManagerFactory(emf).getSessionBroker(); |
| } |
| |
| /** |
| * Create a EclipseLink EMF given a ServerSession that has already been created |
| * and logged in. |
| */ |
| public static jakarta.persistence.EntityManagerFactory createEntityManagerFactory(Server session) { |
| return new EntityManagerFactoryImpl((ServerSession)session); |
| } |
| |
| /** |
| * Create a EclipseLink EMF using a session name and sessions.xml. This is |
| * equivalent to using the EclipseLink.session-xml and EclipseLink.session-name PU |
| * properties with the exception that no persistence.xml is required. |
| * |
| * The application would be required to manage this singleton EMF. |
| */ |
| public static EntityManagerFactory createEntityManagerFactory(String sessionName) { |
| SessionFactory sf = new SessionFactory(sessionName); |
| // Verify that shared session is a ServerSession |
| return new EntityManagerFactoryImpl((ServerSession)sf.getSharedSession()); |
| } |
| |
| |
| |
| /** |
| * If the object has a fetch group then the whole object is read in. |
| */ |
| public static void loadUnfetchedObject(FetchGroupTracker entity) { |
| if(entity._persistence_getFetchGroup() != null) { |
| EntityManagerImpl.processUnfetchedAttribute(entity, null); |
| } |
| } |
| |
| } |