001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.tide.data;
022    
023    import java.io.Serializable;
024    import java.util.List;
025    
026    import javax.persistence.*;
027    
028    import org.granite.logging.Logger;
029    import org.granite.tide.TideTransactionManager;
030    
031    
032    /**
033     * Responsible for attaching a entity with the entity mangager
034     * @author cingram
035     *
036     */
037    public class JPAPersistenceManager extends AbstractTidePersistenceManager implements TideTransactionPersistenceManager {
038            
039            private static final Logger log = Logger.getLogger(JPAPersistenceManager.class);
040            
041            protected EntityManager em;
042    
043            
044            public JPAPersistenceManager(TideTransactionManager tm) {
045                    super(tm);
046            }
047    
048            public JPAPersistenceManager(EntityManager em) {
049                    this(em, null);
050            }
051            
052            public JPAPersistenceManager(EntityManager em, TideTransactionManager tm) {
053                    super(tm != null ? tm : new JPATransactionManager());
054                    
055            if (em == null)
056                    throw new RuntimeException("entity manager cannot be null");
057            
058            this.em =  em;          
059            }
060            
061            public JPAPersistenceManager(EntityManagerFactory emf) {
062                    this(emf, null);
063            }
064            
065            public JPAPersistenceManager(EntityManagerFactory emf, TideTransactionManager tm) {
066                    super(tm != null ? tm : new JPATransactionManager());
067                    
068            if (emf == null)
069                    throw new RuntimeException("entity manager factory cannot be null");
070            
071            this.em = emf.createEntityManager();
072            }
073            
074            public Object getCurrentTransaction() {
075                EntityTransaction et = em.getTransaction();   // Try to get a local resource transaction
076                et.begin();
077                return et;
078            }
079    
080            
081        /**
082         * Finds the entity with the JPA context.
083         * @return the entity with the JPA context.
084         */
085            @Override
086            public Object fetchEntity(Object entity, String[] fetch) {
087                    org.granite.util.Entity tideEntity = new org.granite.util.Entity(entity);
088                    Serializable id = (Serializable)tideEntity.getIdentifier();
089                    
090            if (id == null)
091                return null;
092            
093            if (fetch == null || em.getDelegate().getClass().getName().indexOf(".hibernate.") < 0)
094                    return em.find(entity.getClass(), id);
095            
096            for (String f : fetch) {
097                    Query q = em.createQuery("select e from " + entity.getClass().getName() + " e left join fetch e." + f + " where e = :entity");
098                    q.setParameter("entity", entity);
099                    List<?> results = q.getResultList();
100                    if (!results.isEmpty())
101                            entity = results.get(0);
102                    else
103                            log.warn("Could not find entity %s to initialize, id: %s", entity.getClass().getName(), id);  
104            }
105            return entity;
106            }
107    
108    }