我正在使用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
的方法或类中除外。
答案 0 :(得分:1)
The syntax for that annotation should be: @SelectBeforeUpdate(value=false)