簡體   English   中英

如何避免在spring數據jpa中更新前選擇

[英]how to avoid select before update in spring data jpa

我正在使用 Spring Data Jpa,當我調用jpaRepo.save()進行更新時,有很多 select 語句,我不介意這些實體是否已經在數據庫中更改,只需更新它們。 並且@SelectBeforeUpdate(false)不起作用。

以下是代碼:

產品類別:

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> {

}

產品服務類

package com.heguanyuan.jpa.service;

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

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

產品服務導入類

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 {

}

產品倉庫類

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的方法或類中。

該注釋的語法應該是:@SelectBeforeUpdate(value=false)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM