Exemple #1
0
  @Override
  public void clear() {
    EntityManager em = emf.createEntityManager();
    EntityTransaction txn = em.getTransaction();

    try {
      // the clear operation often deadlocks - let's try several times
      for (int i = 0; ; ++i) {
        txn.begin();
        try {
          log.trace("Clearing JPA Store");
          String entityTable = em.getMetamodel().entity(configuration.entityClass()).getName();
          @SuppressWarnings("unchecked")
          List<Object> items = em.createQuery("FROM " + entityTable).getResultList();
          for (Object o : items) em.remove(o);
          if (configuration.storeMetadata()) {
            String metadataTable = em.getMetamodel().entity(MetadataEntity.class).getName();
            Query clearMetadata = em.createQuery("DELETE FROM " + metadataTable);
            clearMetadata.executeUpdate();
          }
          txn.commit();
          em.clear();
          break;
        } catch (Exception e) {
          log.trace("Failed to clear store", e);
          if (i >= 10) throw new JpaStoreException("Exception caught in clear()", e);
        } finally {
          if (txn != null && txn.isActive()) txn.rollback();
        }
      }
    } finally {
      em.close();
    }
  }
Exemple #2
0
  @Override
  public MarshalledEntry load(Object key) {
    if (!isValidKeyType(key)) {
      return null;
    }

    EntityManager em = emf.createEntityManager();
    try {
      EntityTransaction txn = em.getTransaction();
      long txnBegin = timeService.time();
      txn.begin();
      try {
        long entityFindBegin = timeService.time();
        Object entity = em.find(configuration.entityClass(), key);
        stats.addEntityFind(timeService.time() - entityFindBegin);
        try {
          if (entity == null) return null;
          InternalMetadata m = null;
          if (configuration.storeMetadata()) {
            byte[] keyBytes;
            try {
              keyBytes = marshaller.objectToByteBuffer(key);
            } catch (Exception e) {
              throw new JpaStoreException("Failed to marshall key", e);
            }
            long metadataFindBegin = timeService.time();
            MetadataEntity metadata = em.find(MetadataEntity.class, keyBytes);
            stats.addMetadataFind(timeService.time() - metadataFindBegin);
            if (metadata != null && metadata.getMetadata() != null) {
              try {
                m = (InternalMetadata) marshaller.objectFromByteBuffer(metadata.getMetadata());
              } catch (Exception e) {
                throw new JpaStoreException("Failed to unmarshall metadata", e);
              }
              if (m.isExpired(timeService.wallClockTime())) {
                return null;
              }
            }
          }
          if (trace) log.trace("Loaded " + entity + " (" + m + ")");
          return marshallerEntryFactory.newMarshalledEntry(key, entity, m);
        } finally {
          try {
            txn.commit();
            stats.addReadTxCommitted(timeService.time() - txnBegin);
          } catch (Exception e) {
            stats.addReadTxFailed(timeService.time() - txnBegin);
            throw new JpaStoreException("Failed to load entry", e);
          }
        }
      } finally {
        if (txn != null && txn.isActive()) txn.rollback();
      }
    } finally {
      em.close();
    }
  }
Exemple #3
0
  @Override
  public void write(MarshalledEntry entry) {
    EntityManager em = emf.createEntityManager();

    Object entity = entry.getValue();
    MetadataEntity metadata =
        configuration.storeMetadata()
            ? new MetadataEntity(
                entry.getKeyBytes(),
                entry.getMetadataBytes(),
                entry.getMetadata() == null ? Long.MAX_VALUE : entry.getMetadata().expiryTime())
            : null;
    try {
      if (!configuration.entityClass().isAssignableFrom(entity.getClass())) {
        throw new JpaStoreException(
            String.format(
                "This cache is configured with JPA CacheStore to only store values of type %s - cannot write %s = %s",
                configuration.entityClass().getName(), entity, entity.getClass().getName()));
      } else {
        EntityTransaction txn = em.getTransaction();
        Object id = emf.getPersistenceUnitUtil().getIdentifier(entity);
        if (!entry.getKey().equals(id)) {
          throw new JpaStoreException(
              "Entity id value must equal to key of cache entry: "
                  + "key = ["
                  + entry.getKey()
                  + "], id = ["
                  + id
                  + "]");
        }
        long txnBegin = timeService.time();
        try {
          if (trace) log.trace("Writing " + entity + "(" + toString(metadata) + ")");
          txn.begin();

          long entityMergeBegin = timeService.time();
          em.merge(entity);
          stats.addEntityMerge(timeService.time() - entityMergeBegin);
          if (metadata != null && metadata.hasBytes()) {
            long metadataMergeBegin = timeService.time();
            em.merge(metadata);
            stats.addMetadataMerge(timeService.time() - metadataMergeBegin);
          }

          txn.commit();
          stats.addWriteTxCommited(timeService.time() - txnBegin);
        } catch (Exception e) {
          stats.addWriteTxFailed(timeService.time() - txnBegin);
          throw new JpaStoreException("Exception caught in write()", e);
        } finally {
          if (txn != null && txn.isActive()) txn.rollback();
        }
      }
    } finally {
      em.close();
    }
  }
Exemple #4
0
  public boolean delete(Object key) {
    if (!isValidKeyType(key)) {
      return false;
    }

    EntityManager em = emf.createEntityManager();
    try {
      long entityFindBegin = timeService.time();
      Object entity = em.find(configuration.entityClass(), key);
      stats.addEntityFind(timeService.time() - entityFindBegin);
      if (entity == null) {
        return false;
      }
      MetadataEntity metadata = null;
      if (configuration.storeMetadata()) {
        byte[] keyBytes;
        try {
          keyBytes = marshaller.objectToByteBuffer(key);
        } catch (Exception e) {
          throw new JpaStoreException("Failed to marshall key", e);
        }
        long metadataFindBegin = timeService.time();
        metadata = em.find(MetadataEntity.class, keyBytes);
        stats.addMetadataFind(timeService.time() - metadataFindBegin);
      }

      EntityTransaction txn = em.getTransaction();
      if (trace) log.trace("Removing " + entity + "(" + toString(metadata) + ")");
      long txnBegin = timeService.time();
      txn.begin();
      try {
        long entityRemoveBegin = timeService.time();
        em.remove(entity);
        stats.addEntityRemove(timeService.time() - entityRemoveBegin);
        if (metadata != null) {
          long metadataRemoveBegin = timeService.time();
          em.remove(metadata);
          stats.addMetadataRemove(timeService.time() - metadataRemoveBegin);
        }
        txn.commit();
        stats.addRemoveTxCommitted(timeService.time() - txnBegin);
        return true;
      } catch (Exception e) {
        stats.addRemoveTxFailed(timeService.time() - txnBegin);
        throw new JpaStoreException("Exception caught in delete()", e);
      } finally {
        if (txn != null && txn.isActive()) txn.rollback();
      }
    } finally {
      em.close();
    }
  }
Exemple #5
0
 protected boolean isValidKeyType(Object key) {
   return emf.getMetamodel()
       .entity(configuration.entityClass())
       .getIdType()
       .getJavaType()
       .isAssignableFrom(key.getClass());
 }
Exemple #6
0
  @Override
  public boolean contains(Object key) {
    if (!isValidKeyType(key)) {
      return false;
    }

    EntityManager em = emf.createEntityManager();
    try {
      EntityTransaction txn = em.getTransaction();
      long txnBegin = timeService.time();
      txn.begin();
      try {
        long entityFindBegin = timeService.time();
        Object entity = em.find(configuration.entityClass(), key);
        stats.addEntityFind(timeService.time() - entityFindBegin);
        if (trace) log.trace("Entity " + key + " -> " + entity);
        try {
          if (entity == null) return false;
          if (configuration.storeMetadata()) {
            byte[] keyBytes;
            try {
              keyBytes = marshaller.objectToByteBuffer(key);
            } catch (Exception e) {
              throw new JpaStoreException("Cannot marshall key", e);
            }
            long metadataFindBegin = timeService.time();
            MetadataEntity metadata = em.find(MetadataEntity.class, keyBytes);
            stats.addMetadataFind(timeService.time() - metadataFindBegin);
            if (trace) log.trace("Metadata " + key + " -> " + toString(metadata));
            return metadata == null || metadata.expiration > timeService.wallClockTime();
          } else {
            return true;
          }
        } finally {
          txn.commit();
          stats.addReadTxCommitted(timeService.time() - txnBegin);
        }
      } catch (RuntimeException e) {
        stats.addReadTxFailed(timeService.time() - txnBegin);
        throw e;
      } finally {
        if (txn != null && txn.isActive()) txn.rollback();
      }
    } finally {
      em.close();
    }
  }
Exemple #7
0
 @Override
 public void stop() {
   try {
     emfRegistry.closeEntityManagerFactory(configuration.persistenceUnitName());
   } catch (Exception e) {
     throw new JpaStoreException("Exceptions occurred while stopping store", e);
   } finally {
     log.info("JPA Store stopped, stats: " + stats);
   }
 }
Exemple #8
0
 @Override
 public int size() {
   EntityManager em = emf.createEntityManager();
   try {
     CriteriaBuilder builder = em.getCriteriaBuilder();
     CriteriaQuery<Long> cq = builder.createQuery(Long.class);
     cq.select(builder.count(cq.from(configuration.entityClass())));
     return em.createQuery(cq).getSingleResult().intValue();
   } finally {
     em.close();
   }
 }
Exemple #9
0
  @Override
  public void start() {
    try {
      this.emf = emfRegistry.getEntityManagerFactory(configuration.persistenceUnitName());
    } catch (PersistenceException e) {
      throw new JpaStoreException(
          "Persistence Unit [" + this.configuration.persistenceUnitName() + "] not found", e);
    }

    ManagedType<?> mt;
    try {
      mt = emf.getMetamodel().entity(this.configuration.entityClass());
    } catch (IllegalArgumentException e) {
      throw new JpaStoreException(
          "Entity class ["
              + this.configuration.entityClass().getName()
              + " specified in configuration is not recognized by the EntityManagerFactory with Persistence Unit ["
              + this.configuration.persistenceUnitName()
              + "]",
          e);
    }

    if (!(mt instanceof IdentifiableType)) {
      throw new JpaStoreException(
          "Entity class must have one and only one identifier (@Id or @EmbeddedId)");
    }
    IdentifiableType<?> it = (IdentifiableType<?>) mt;
    if (!it.hasSingleIdAttribute()) {
      throw new JpaStoreException(
          "Entity class has more than one identifier.  It must have only one identifier.");
    }

    Type<?> idType = it.getIdType();
    Class<?> idJavaType = idType.getJavaType();

    if (idJavaType.isAnnotationPresent(GeneratedValue.class)) {
      throw new JpaStoreException(
          "Entity class has one identifier, but it must not have @GeneratedValue annotation");
    }
  }
Exemple #10
0
  @Override
  public void purge(Executor threadPool, final PurgeListener listener) {
    ExecutorAllCompletionService eacs = new ExecutorAllCompletionService(threadPool);
    EntityManager em = emf.createEntityManager();
    try {
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<MetadataEntity> cq = cb.createQuery(MetadataEntity.class);

      Root root = cq.from(MetadataEntity.class);
      long currentTime = timeService.wallClockTime();
      cq.where(cb.le(root.get(MetadataEntity.EXPIRATION), currentTime));

      for (MetadataEntity metadata : em.createQuery(cq).getResultList()) {
        EntityTransaction txn = em.getTransaction();
        final Object key;
        try {
          key = marshaller.objectFromByteBuffer(metadata.name);
        } catch (Exception e) {
          throw new JpaStoreException("Cannot unmarshall key", e);
        }
        long txnBegin = timeService.time();
        txn.begin();
        try {
          long metadataFindBegin = timeService.time();
          metadata = em.find(MetadataEntity.class, metadata.name);
          stats.addMetadataFind(timeService.time() - metadataFindBegin);
          // check for transaction - I hope write skew check is done here
          if (metadata.expiration > currentTime) {
            txn.rollback();
            continue;
          }
          long entityFindBegin = timeService.time();
          Object entity = em.find(configuration.entityClass(), key);
          stats.addEntityFind(timeService.time() - entityFindBegin);
          if (entity != null) { // the entry may have been removed
            long entityRemoveBegin = timeService.time();
            em.remove(entity);
            stats.addEntityRemove(timeService.time() - entityRemoveBegin);
          }
          long metadataRemoveBegin = timeService.time();
          em.remove(metadata);
          stats.addMetadataRemove(timeService.time() - metadataRemoveBegin);
          txn.commit();
          stats.addRemoveTxCommitted(timeService.time() - txnBegin);

          if (trace) log.trace("Expired " + key + " -> " + entity + "(" + toString(metadata) + ")");
          if (listener != null) {
            eacs.submit(
                new Runnable() {
                  @Override
                  public void run() {
                    listener.entryPurged(key);
                  }
                },
                null);
          }
        } catch (RuntimeException e) {
          stats.addRemoveTxFailed(timeService.time() - txnBegin);
          throw e;
        } finally {
          if (txn != null && txn.isActive()) {
            txn.rollback();
          }
        }
      }
    } finally {
      em.close();
    }
    eacs.waitUntilAllCompleted();
    if (eacs.isExceptionThrown()) {
      throw new JpaStoreException(eacs.getFirstException());
    }
  }
Exemple #11
0
  @Override
  public void process(
      KeyFilter filter,
      final CacheLoaderTask task,
      Executor executor,
      boolean fetchValue,
      final boolean fetchMetadata) {
    ExecutorAllCompletionService eacs = new ExecutorAllCompletionService(executor);
    final TaskContextImpl taskContext = new TaskContextImpl();
    EntityManager em = emf.createEntityManager();

    try {
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery cq = cb.createQuery();
      Root root = cq.from(configuration.entityClass());
      Type idType = root.getModel().getIdType();
      SingularAttribute idAttr = root.getModel().getId(idType.getJavaType());
      cq.select(root.get(idAttr));

      for (final Object key : em.createQuery(cq).getResultList()) {
        if (taskContext.isStopped()) break;
        if (filter != null && !filter.shouldLoadKey(key)) {
          if (trace) log.trace("Key " + key + " filtered");
          continue;
        }
        EntityTransaction txn = em.getTransaction();

        Object tempEntity = null;
        InternalMetadata tempMetadata = null;
        boolean loaded = false;
        txn.begin();
        try {
          do {
            try {
              tempEntity = fetchValue ? em.find(configuration.entityClass(), key) : null;
              tempMetadata = fetchMetadata ? getMetadata(em, key) : null;
            } finally {
              try {
                txn.commit();
                loaded = true;
              } catch (Exception e) {
                log.trace("Failed to load once", e);
              }
            }
          } while (!loaded);
        } finally {
          if (txn != null && txn.isActive()) txn.rollback();
        }
        final Object entity = tempEntity;
        final InternalMetadata metadata = tempMetadata;
        if (trace) log.trace("Processing " + key + " -> " + entity + "(" + metadata + ")");

        if (metadata != null && metadata.isExpired(timeService.wallClockTime())) continue;
        eacs.submit(
            new Callable<Void>() {
              @Override
              public Void call() throws Exception {
                try {
                  final MarshalledEntry marshalledEntry =
                      marshallerEntryFactory.newMarshalledEntry(key, entity, metadata);
                  if (marshalledEntry != null) {
                    task.processEntry(marshalledEntry, taskContext);
                  }
                  return null;
                } catch (Exception e) {
                  log.errorExecutingParallelStoreTask(e);
                  throw e;
                }
              }
            });
      }
      eacs.waitUntilAllCompleted();
      if (eacs.isExceptionThrown()) {
        throw new org.infinispan.persistence.spi.PersistenceException(
            "Execution exception!", eacs.getFirstException());
      }
    } finally {
      em.close();
    }
  }