2009-03-13 12 views
3

Ich habe Probleme mit einigen Caching mit Hibernate arbeiten genau so, wie ich möchte. Ich habe einen Beispielcode erstellt, um dieses Problem zu replizieren."Zwischengespeicherter Artikel wurde gesperrt" verursacht Select-Anweisung in Hibernate

Ich habe ein Objekt, das Instanzen von sich selbst enthält. Zum Beispiel ein Teil, der aus mehr Teilen besteht.

Ich brauche wirklich die select-Anweisungen zu minimieren, dass Hibernate ist, wenn ein aktualisiertes Objekt kommt nach durch die Protokolle gehen, ich diese Protokollausgabe sehen, die eine SELECT-Anweisung verursacht.

Cached Artikel gesperrt wurde : com.cache.dataobject.Part.parts # 1

Was kann ich in meinen Anmerkungszuordnungen, XML-Dateien, Caching-Providern oder Logik ändern, damit das zwischengespeicherte Objekt nicht gesperrt wird? Ich möchte diese Select-Aussage wirklich loswerden.

Ich habe die Entity, DataObject, Code, mit dem ich teste, und Protokollausgabe.

Hibernate Version: 3,4

EHCache Version: 1.2.3 (mit dem Hibernate Download)

Part Datenobjekt:

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; 
    } 

} 

CacheDao:

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; 
    } 

} 

Test Client-Code:

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(); 
     } 

    } 

} 

persistence.xml

<?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.xml

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

Ausgabeprotokoll:

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 
+0

Haben Sie die Hibernate-Liste versucht? –

+0

Ja habe ich .. Ich warte immer noch auf etwas von ihnen. – systemoutprintln

Antwort

1

Sie haben es wahrscheinlich schon gesehen, aber es ist ein offener Hibernate Fehler, der zu Ihrem Problem zu beziehen scheint - "2nd level cached collections are locked causing a cache miss"..

Von diesem Fehler kann die Korrektur eine neue Sitzung für Ihre hinzufügen/aktualisieren Anrufe verwenden. Sie können eine EntityManagerFactory anstelle von EntityManager abrufen und für jeden Aufruf einen neuen Entity Manager anfordern. Offensichtlich hängt es vom weiteren Kontext Ihres Codes ab, wie angemessen das ist.