Java “缓存项已锁定”导致Hibernate中的Select语句

Java “缓存项已锁定”导致Hibernate中的Select语句,java,hibernate,jpa,ehcache,second-level-cache,Java,Hibernate,Jpa,Ehcache,Second Level Cache,我在使用hibernate进行缓存时遇到了问题,这正是我想要的。我创建了一些示例代码来复制我遇到的这个问题 我有一个包含自身实例的对象。例如,由多个零件组成的零件 我真的需要最小化Hibernate在更新对象进入时使用的select语句。查看日志后,我看到这个日志输出导致SELECT语句: 已锁定缓存项:com.cache.dataobject.Part.parts1 我可以在注释映射、xml文件、缓存提供程序或逻辑中更改哪些内容来防止缓存项被锁定?我真的很想摆脱select语句 我包括了实体、

我在使用hibernate进行缓存时遇到了问题,这正是我想要的。我创建了一些示例代码来复制我遇到的这个问题

我有一个包含自身实例的对象。例如,由多个零件组成的零件

我真的需要最小化Hibernate在更新对象进入时使用的select语句。查看日志后,我看到这个日志输出导致SELECT语句:

已锁定缓存项:com.cache.dataobject.Part.parts1

我可以在注释映射、xml文件、缓存提供程序或逻辑中更改哪些内容来防止缓存项被锁定?我真的很想摆脱select语句

我包括了实体、数据对象、测试代码和日志输出

休眠版本:3.4

EHCache版本:1.2.3随Hibernate下载提供

零件数据对象:

测试客户端代码:


您可能已经看到了这一点,但是有一个开放的Hibernate bug似乎与您的问题有关-


从这个bug中,修复方法可能是使用新会话进行添加/更新调用。您可以获得EntityManager工厂而不是EntityManager,并为每个调用请求一个新的实体管理器。显然,这取决于您的代码的更广泛的上下文,以确定这是否合适。

您是否尝试过Hibernate列表?是的,我尝试过。。还在等他们的消息。
package com.cache.dataobject;

import java.io.Serializable;
import java.lang.String;
import java.util.List;

import javax.persistence.*;

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

import static javax.persistence.CascadeType.ALL;

/**
 * Entity implementation class for Entity: Part
 * 
 */
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Part implements Serializable {

    private int id;
    private String name;
    private static final long serialVersionUID = 1L;
    private Part mainPart;
    private List<Part> parts;

    public Part() {
        super();
    }

    @Id
    public int getId() {
        return this.id;
    }

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

    @Column(name = "PART_NAME")
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToOne(cascade = ALL)
    public Part getMainPart() {
        return mainPart;
    }

    public void setMainPart(Part mainPart) {
        this.mainPart = mainPart;
    }

    @OneToMany(cascade = ALL)
    @JoinColumn(name = "mainPart_id", referencedColumnName = "id")
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public List<Part> getParts() {
        return parts;
    }

    public void setParts(List<Part> parts) {
        this.parts = parts;
    }

}
package com.cache.dao;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.cache.dataobject.Part;

/**
 * Session Bean implementation class CacheDao
 */
@Stateless(mappedName = "ejb/CacheDao")
public class CacheDao implements CacheDaoRemote {

    @PersistenceContext(unitName="CacheProjectUnit")
    EntityManager em;

    /**
     * Default constructor. 
     */
    public CacheDao() {
        // TODO Auto-generated constructor stub
    }

    public Part addPart(Part part){
        System.out.println("CALLED PERSIST");
        em.persist(part);
        return part;
    }

    public Part updatePart(Part part){
        System.out.println("CALLED MERGE");
        em.merge(part);
        return part;
    }

}
package com.cache.dao;

import java.util.ArrayList;
import java.util.List;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.cache.dao.CacheDaoRemote;
import com.cache.dataobject.Part;


public class test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        InitialContext ctx;
        try {
            ctx = new InitialContext();
            CacheDaoRemote dao = (CacheDaoRemote) ctx.lookup("ejb/CacheDao");
            Part computer = new Part();
            computer.setId(1);
            computer.setName("Computer");

            List<Part> parts = new ArrayList<Part>();

            Part cpu = new Part();
            cpu.setId(2);
            cpu.setName("CPU");

            Part monitor = new Part();
            monitor.setId(3);
            monitor.setName("Monitor");

            parts.add(cpu);
            parts.add(monitor);

            computer.setParts(parts);

            dao.addPart(computer);

            computer.setName("DellComputer");

            dao.updatePart(computer);


        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="CacheProjectUnit">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!-- JNDI name of the database resource to use -->
        <jta-data-source>jdbc/H2Pool</jta-data-source>
        <properties>
            <!-- The database dialect to use -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
            <!-- drop and create tables at deployment -->
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
            <property name="hibernate.max_fetch_depth" value="3" />
            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
        </properties>
    </persistence-unit>
</persistence>
<ehcache>
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />


    <cache name = "com.cache.dataobject.Part"
        maxElementsInMemory="100000"
        eternal="true"
        diskPersistent="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
    />


    <cache name = "com.cache.dataobject.Part.parts"
        maxElementsInMemory="100000"
        eternal="true"
        diskPersistent="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
    />


</ehcache>
INFO: CALLED PERSIST
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: Element for com.cache.dataobject.Part#1 is null
FINEST: Cache miss: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINE: Element for com.cache.dataobject.Part#2 is null
FINEST: Cache miss: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINE: Element for com.cache.dataobject.Part#3 is null
FINEST: Cache miss: com.cache.dataobject.Part#3
FINEST: Invalidating: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINE: Element for com.cache.dataobject.Part.parts#1 is null
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: update Part set mainPart_id=? where id=?
FINE: update Part set mainPart_id=? where id=?
FINEST: Inserting: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: Element for com.cache.dataobject.Part#1 is null
FINEST: Inserted: com.cache.dataobject.Part#1
FINEST: Inserting: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINE: Element for com.cache.dataobject.Part#2 is null
FINEST: Inserted: com.cache.dataobject.Part#2
FINEST: Inserting: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINE: Element for com.cache.dataobject.Part#3 is null
FINEST: Inserted: com.cache.dataobject.Part#3
FINEST: Releasing: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1

INFO: CALLED MERGE
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Cache hit: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Cache hit: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINEST: Cache hit: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINEST: Cache hit: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINEST: Cache hit: com.cache.dataobject.Part#3
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINEST: Cache hit: com.cache.dataobject.Part#3
FINEST: Cache lookup: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Cached item was locked: com.cache.dataobject.Part.parts#1
FINE: select parts0_.mainPart_id as mainPart3_1_, parts0_.id as id1_, parts0_.id as id18_0_, parts0_.mainPart_id as mainPart3_18_0_, parts0_.PART_NAME as PART2_18_0_ from Part parts0_ where parts0_.mainPart_id=?
FINEST: Caching: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Cached: com.cache.dataobject.Part.parts#1
FINEST: Invalidating: com.cache.dataobject.Part.parts#2
FINE: key: com.cache.dataobject.Part.parts#2
FINE: Element for com.cache.dataobject.Part.parts#2 is null
FINEST: Invalidating: com.cache.dataobject.Part.parts#3
FINE: key: com.cache.dataobject.Part.parts#3
FINE: Element for com.cache.dataobject.Part.parts#3 is null
FINEST: Invalidating: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Invalidating: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: update Part set mainPart_id=?, PART_NAME=? where id=?
FINE: update Part set mainPart_id=null where mainPart_id=?
FINE: update Part set mainPart_id=null where mainPart_id=?
FINEST: Updating: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Updated: com.cache.dataobject.Part#1
FINEST: Releasing: com.cache.dataobject.Part.parts#2
FINE: key: com.cache.dataobject.Part.parts#2
FINEST: Releasing: com.cache.dataobject.Part.parts#3
FINE: key: com.cache.dataobject.Part.parts#3
FINEST: Releasing: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1