ack_Finding 2017-12-05 06:04 采纳率: 0%
浏览 2597

为什么开启了JPA二级缓存,查询第一次后,再次查询,还有一半的数据需要到数据库查询呢

@Test
public void testA(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("homework");
//开启第一个EntityManager
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
ArticleType type = entityManager.find(ArticleType.class,2);
// 同一个EntityManager里面,查询多次同一个主键的对象,只会查询一次
// 这个时候就是【一级缓存】在发生作用,一级缓存作用在EntityManager、Session级别。
for(long i = 1;i<4;i++){
Article aritcle = entityManager.find(Article.class, i);
}
entityManager.getTransaction().commit();
entityManager.close();
System.out.println("--------------------------------------");
//开启第二个EntityManager
EntityManager entityManager2 = factory.createEntityManager();
entityManager2.getTransaction().begin();
for(long i = 1;i<4;i++){
Article aritcle = entityManager2.find(Article.class, i);
}
System.out.println("=============================================");
entityManager2.getTransaction().commit();
entityManager2.close();
factory.close();
}
@Test
public void testB(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("homework");
//开启第一个EntityManager
EntityManager manager = factory.createEntityManager();
manager.getTransaction().begin();
for(long i = 800;i<820;i++){
Order order = manager.find(Order.class, i);
}
manager.getTransaction().commit();
manager.close();
System.out.println("--------------------------------------");
//开启第二个EntityManager
EntityManager manager2 = factory.createEntityManager();
manager2.getTransaction().begin();
for(long i = 800;i<820;i++){
Order order = manager2.find(Order.class, i);
}
manager2.getTransaction().commit();
manager2.close();
factory.close();
}



测试结果:
可以看到testA()二级缓存运行正常
testB()二级缓存运行不正常,还有大概一半数据从数据库查询
ArticleType代码:
import java.util.List;

import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name="ec_article_type")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class ArticleType implements java.io.Serializable{

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int code;//分类编号
private String name;//分类名称
private String remark;//备注

@OneToMany(mappedBy = "type",cascade=CascadeType.PERSIST)
private List<Article> articles;

public List<Article> getArticles() {
    return articles;
}
public void setArticles(List<Article> articles) {
    this.articles = articles;
}

public int getCode() {
    return code;
}
public void setCode(int code) {
    this.code = code;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getRemark() {
    return remark;
}
public void setRemark(String remark) {
    this.remark = remark;
}

}


Article代码:
@Entity
@Table(name="EC_ARTICLE")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Article implements Serializable{
private static final long serialVersionUID = -7399089680020291155L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String supplier;
private Double price;
private Double discount;//折扣
private String locality;
private Date putawayDate;
private int storage;
private String image;
private String description;
private Date createDate;
// 是否禁用,数据库里面如果是0,表示false,未禁用;
// 数据库是1的时候,表示true,是禁用的!
private boolean disabled;

//多对一,在多端维护
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="type_Code")
private ArticleType type;

public ArticleType getType() {
    return type;
}
public void setType(ArticleType type) {
    this.type = type;
}
public Double getDiscountPrice(){
    DecimalFormat fmt = new DecimalFormat("#.00");
    if(discount != null){
        String discountPrice = fmt.format(price*discount/10);
        return Double.valueOf(discountPrice);
    }else{
        return 0D;
    }

}
public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public String getSupplier() {
    return supplier;
}
public void setSupplier(String supplier) {
    this.supplier = supplier;
}
public Double getPrice() {
    return price;
}
public void setPrice(Double price) {
    this.price = price;
}
public Double getDiscount() {
    return discount;
}
public void setDiscount(Double discount) {
    this.discount = discount;
}
public String getLocality() {
    return locality;
}
public void setLocality(String locality) {
    this.locality = locality;
}
public Date getPutawayDate() {
    return putawayDate;
}
public void setPutawayDate(Date putawayDate) {
    this.putawayDate = putawayDate;
}
public int getStorage() {
    return storage;
}
public void setStorage(int storage) {
    this.storage = storage;
}
public String getImage() {
    return image;
}
public void setImage(String image) {
    this.image = image;
}
public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}
public Date getCreateDate() {
    return createDate;
}
public void setCreateDate(Date createDate) {
    this.createDate = createDate;
}
public boolean isDisabled() {
    return disabled;
}
public void setDisabled(boolean disabled) {
    this.disabled = disabled;
}

Order代码:
@Entity
@Table(name="EC_ORDER")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Order implements java.io.Serializable{

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderCode;
private java.util.Date createDate;
private java.util.Date sendDate;//发货时间
private String status;//订单状态
private double amount;//订单总价

//多个订单对应一个用户
@ManyToOne
private User user;

//一对多,在1端维护
//一个订单对应多个订单明细:一对多关系
@OneToMany(mappedBy="order",cascade=CascadeType.PERSIST)
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
Set<OrderItem> orderItems;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getOrderCode() {
    return orderCode;
}

public void setOrderCode(String orderCode) {
    this.orderCode = orderCode;
}

public java.util.Date getCreateDate() {
    return createDate;
}

public void setCreateDate(java.util.Date createDate) {
    this.createDate = createDate;
}

public java.util.Date getSendDate() {
    return sendDate;
}

public void setSendDate(java.util.Date sendDate) {
    this.sendDate = sendDate;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public double getAmount() {
    return amount;
}

public void setAmount(double amount) {
    this.amount = amount;
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

public Set<OrderItem> getOrderItems() {
    return orderItems;
}

public void setOrderItems(Set<OrderItem> orderItems) {
    this.orderItems = orderItems;
}

}
OrderItem代码:
@Entity
@Table(name="EC_ORDER_ITEM")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class OrderItem implements java.io.Serializable{
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;//订单明细id
private int orderNum;//当个商品购买的数量

//多对一(在1端维护)
@ManyToOne
@JoinColumn(name="order_id")
private Order order;

//多对一查询,一个订单明细对应一个商品
@ManyToOne
@JoinColumn(name = "article_id")
private Article article;


public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public Order getOrder() {
    return order;
}
public void setOrder(Order order) {
    this.order = order;
}
public int getOrderNum() {
    return orderNum;
}
public void setOrderNum(int orderNum) {
    this.orderNum = orderNum;
}
public Article getArticle() {
    return article;
}
public void setArticle(Article article) {
    this.article = article;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((article == null) ? 0 : article.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    OrderItem other = (OrderItem) obj;
    if (article == null) {
        if (other.article != null)
            return false;
    } else if (!article.equals(other.article))
        return false;
    return true;
}

}

  • 写回答

1条回答 默认 最新

  • lichdb 2018-01-01 17:10
    关注

    在第一次查询运行完以后,检查下缓存中的数据,是不是只有前10条缓存了,如果是,则可能是缓存过小等问题,可以加大缓存继续测试

    评论

报告相同问题?

悬赏问题

  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档
  • ¥50 C++五子棋AI程序编写
  • ¥30 求安卓设备利用一个typeC接口,同时实现向pc一边投屏一边上传数据的解决方案。