2017-10-08 89 views
1

我正在使用Spring Data Jpa,当我调用jpaRepo.save()进行更新时,有很多select语句,我不介意这些实例在数据库中是否已更改,只需更新它们。 和@SelectBeforeUpdate(false)不起作用。如何避免在更新之前选择弹簧数据jpa

下面是代码:

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); 
    } 
} 

当我打电话productService.save(entity),总会有很多的SELECT语句,除了在方法或类@Transactional

+0

可否请你发布你现在的代码?只是与这个问题有关的部分。 – Assafs

+1

@Assafs我已经发布了代码,感谢您的帮助,如有必要,我可以发布所有源代码。 –

回答

1

该注释的语法应为: @SelectBeforeUpdate(值= FALSE)

+0

我认为只有一个参数时,“@SelectBeforeUpdate(false)”可以。 –

+0

感谢您的澄清。我只看到它的值=。 – Jeff

+0

看看这个答案:https://stackoverflow.com/questions/16303691/hibernate-select-before-update –