如何避免在更新spring data jpa之前选择

时间:2017-10-08 07:46:46

标签: java spring hibernate spring-data-jpa persistence

我正在使用Spring Data Jpa,当我调用jpaRepo.save()进行更新时,有很多select语句,我不介意如果这些entites已在数据库中更改,只需更新它们。 并且@SelectBeforeUpdate(false)无效。

以下是代码:

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的方法或类中除外。

1 个答案:

答案 0 :(得分:1)

The syntax for that annotation should be: @SelectBeforeUpdate(value=false)