2017-10-08 54 views
1

J'utilise Spring Data Jpa, quand j'appelle jpaRepo.save() pour la mise à jour, il y a beaucoup de déclaration de sélection, je ne me dérange pas si ces entités sont déjà changées dans la base de données, juste les mettre à jour . Et @SelectBeforeUpdate(false) ne fonctionne pas.comment éviter sélectionner avant la mise à jour dans les données de printemps jpa

Voici les codes:

Product.class:

package com.heguanyuan.jpa.domain; 

import com.heguanyuan.jpa.core.MyPersistenceAble; 
import org.hibernate.annotations.*; 

import javax.persistence.*; 
import javax.persistence.CascadeType; 
import javax.persistence.Entity; 
import java.util.Set; 

@Entity 
@NamedEntityGraphs({ 
     @NamedEntityGraph(name = "Product.detail", attributeNodes = { 
       @NamedAttributeNode("description"), 
       @NamedAttributeNode(value = "skus", subgraph = "Product.Sku.detail"), 
       @NamedAttributeNode("pictures") 
     }, subgraphs = { 
       @NamedSubgraph(type = Sku.class, name = "Product.Sku.detail", attributeNodes = { 
         @NamedAttributeNode(value = "pictures") 
       }) 
     }) 
}) 
@SelectBeforeUpdate(value = false) 
public class Product extends MyPersistenceAble<Long> { 

    private String title; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "product") 
    private Description description; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.EAGER, orphanRemoval = true) 
    private Set<Sku> skus; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.EAGER, orphanRemoval = true) 
    @Where(clause = "type = 'product'") 
    private Set<ProductPicture> pictures; 
// getter and setter 
} 

package com.heguanyuan.jpa.core; 

import org.springframework.data.jpa.domain.AbstractPersistable; 

import javax.persistence.MappedSuperclass; 
import java.io.Serializable; 

MyPersistenceAble.class:

package com.heguanyuan.jpa.core; 

import org.springframework.data.jpa.domain.AbstractPersistable; 

import javax.persistence.MappedSuperclass; 
import java.io.Serializable; 

@MappedSuperclass 
public abstract class MyPersistenceAble<PK extends Serializable> extends AbstractPersistable<PK> { 

} 

ProductService.class

package com.heguanyuan.jpa.service; 

import com.heguanyuan.jpa.domain.Product; 
import com.heguanyuan.jpa.core.PersistenceService; 

public interface ProductService extends PersistenceService<Product, Long> { 
} 

ProductServiceImp.class

package com.heguanyuan.jpa.service.imp; 

import com.heguanyuan.jpa.core.AbstractPersistenceService; 
import com.heguanyuan.jpa.domain.Product; 
import com.heguanyuan.jpa.service.ProductService; 
import org.springframework.stereotype.Service; 

@Service 
public class ProductServiceImp extends AbstractPersistenceService<Product, Long> implements ProductService { 

} 

ProductRepo.class

package com.heguanyuan.jpa.repo; 

import com.heguanyuan.jpa.domain.Product; 
import org.springframework.data.jpa.repository.EntityGraph; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.Query; 

import java.util.List; 

public interface ProductRepo extends JpaRepository<Product, Long> { 

    @Override 
    @EntityGraph(value = "Product.detail", type = EntityGraph.EntityGraphType.LOAD) 
    List<Product> findAll(); 
} 

AbstractPersistenceServiceImp.class

package com.heguanyuan.jpa.core; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.domain.Example; 
import org.springframework.data.domain.Page; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.domain.Sort; 
import org.springframework.data.jpa.repository.JpaRepository; 

import javax.persistence.EntityGraph; 
import javax.persistence.EntityManager; 
import javax.persistence.TypedQuery; 
import javax.persistence.criteria.CriteriaBuilder; 
import javax.persistence.criteria.CriteriaQuery; 
import javax.persistence.criteria.Root; 
import javax.transaction.Transactional; 
import java.io.Serializable; 
import java.lang.reflect.ParameterizedType; 
import java.lang.reflect.Type; 
import java.util.List; 

@Transactional 
public abstract class AbstractPersistenceServiceImp<T, ID extends Serializable> implements PersistenceService<T, ID> { 

    @Autowired 
    private JpaRepository<T, ID> repository; 

    @Autowired 
    private EntityManager em; 

    private Class<T> type; 

    { 
     Type superclass = getClass().getGenericSuperclass(); 
     Type[] typeArguments = ((ParameterizedType) superclass).getActualTypeArguments(); 
     type = (Class<T>) typeArguments[0]; 
    } 

    @Override 
    public List<T> findAll() { 

     CriteriaBuilder builder = em.getCriteriaBuilder(); 
     CriteriaQuery<T> criteriaQuery = builder.createQuery(type); 
     Root<T> rootEntry = criteriaQuery.from(type); 
     CriteriaQuery<T> all = criteriaQuery.select(rootEntry); 
     all.distinct(true); 
     TypedQuery<T> typedQuery = em.createQuery(all); 

     /* 默认使用第一个 EntityGraph*/ 
     List<EntityGraph<? super T>> graphs = em.getEntityGraphs(type); 
     EntityGraph<? super T> graph; 
     if (graphs.size() > 0) { 
      graph = graphs.get(0); 
      typedQuery.setHint("javax.persistence.loadgraph", graph); 
     } 

     return typedQuery.getResultList(); 
    } 

    @Override 
    public <S extends T> S save(S entity) { 
     return repository.save(entity); 
    } 

    @Override 
    public List<T> findAll(Iterable<ID> ids) { 
     return repository.findAll(ids); 
    } 

    @Override 
    public <S extends T> List<S> save(Iterable<S> iterable) { 
     return repository.save(iterable); 
    } 

    @Override 
    public <S extends T> S saveAndFlush(S s) { 
     return repository.saveAndFlush(s); 
    } 

    @Override 
    public void deleteInBatch(Iterable<T> iterable) { 
     repository.deleteInBatch(iterable); 
    } 

    @Override 
    public T findOne(ID id) { 
     return repository.findOne(id); 
    } 

    @Override 
    public long count() { 
     return repository.count(); 
    } 

    @Override 
    public <S extends T> List<S> findAll(Example<S> example) { 
     return repository.findAll(example); 
    } 

    @Override 
    public <S extends T> List<S> findAll(Example<S> example, Sort sort) { 
     return repository.findAll(example, sort); 
    } 


    @Override 
    public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) { 
     return repository.findAll(example, pageable); 
    } 

    @Override 
    public Page<T> findAll(Pageable pageable) { 
     return repository.findAll(pageable); 
    } 
} 

quand je l'appelle productService.save(entity), il y a toujours beaucoup instruction select, sauf dans une méthode ou une classe avec @Transactional.

+0

Pourriez-vous s'il vous plaît poster le code que vous avez maintenant? Juste les parties pertinentes à cette question. – Assafs

+1

@Assafs J'ai posté le code, merci de m'aider, je peux poster tout le code source si nécessaire. –

Répondre

1

La syntaxe de cette annotation doit être: @SelectBeforeUpdate (valeur = false)

+0

Je pense que quand il n'y a qu'un seul paramètre, '@SelectBeforeUpdate (false)' est ok. –

+0

Merci pour la clarification. Je l'ai seulement vu avec de la valeur =. – Jeff

+0

Vérifiez cette réponse: https://stackoverflow.com/questions/16303691/hibernate-select-before-update –