I have been trying to figure out this problem for a month or so now, and it has been driving me crazy.
Basically I want to keep this from happening:
FINEST: Cached item was locked: com.cache.dataobject.Part.parts#0
FINE: select parts0_.mainPart_id as mainPart3_1_, parts0_.id as id1_, parts0_.id as id182_0_, parts0_.mainPart_id as mainPart3_182_0_, parts0_.PART_NAME as PART2_182_0_ from SourcePart parts0_ where parts0_.mainPart_id=?
Since that select statement isn't really necessary.
If you have any ideas please help. It feels like I have tried a million different things to no avail.
I have included the DAO EJB I am using, the Cache/Hibernate Debug Log, the JPA Entities, and the Test code I have been using.
Debug Log:
INFO: CALLED PERSIST
INFO: com.cache.dao._CacheDao_Serializable@65e34c
FINEST: Cache lookup: com.cache.dataobject.Part#0
FINEST: Cache miss: com.cache.dataobject.Part#0
FINEST: Cache lookup: com.cache.dataobject.SourcePart#1
FINEST: Cache miss: com.cache.dataobject.SourcePart#1
FINEST: Cache lookup: com.cache.dataobject.SourcePart#2
FINEST: Cache miss: com.cache.dataobject.SourcePart#2
FINEST: Invalidating: com.cache.dataobject.Part.parts#0
FINE: insert into Part (PART_NAME, id) values (?, ?)
FINE: insert into SourcePart (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: insert into SourcePart (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: update SourcePart set mainPart_id=? where id=?
FINE: update SourcePart set mainPart_id=? where id=?
FINEST: Inserting: com.cache.dataobject.Part#0
FINEST: Inserted: com.cache.dataobject.Part#0
FINEST: Inserting: com.cache.dataobject.SourcePart#1
FINEST: Inserted: com.cache.dataobject.SourcePart#1
FINEST: Inserting: com.cache.dataobject.SourcePart#2
FINEST: Inserted: com.cache.dataobject.SourcePart#2
FINEST: Releasing: com.cache.dataobject.Part.parts#0
INFO: CALLED MULTI MERGE
FINEST: Cache lookup: com.cache.dataobject.Part#0
FINEST: Cache hit: com.cache.dataobject.Part#0
FINEST: Cache lookup: com.cache.dataobject.Part#0
FINEST: Cache hit: com.cache.dataobject.Part#0
FINEST: Cache lookup: com.cache.dataobject.Part.parts#0
FINEST: Cached item was locked: com.cache.dataobject.Part.parts#0
FINE: select parts0_.mainPart_id as mainPart3_1_, parts0_.id as id1_, parts0_.id as id182_0_, parts0_.mainPart_id as mainPart3_182_0_, parts0_.PART_NAME as PART2_182_0_ from SourcePart parts0_ where parts0_.mainPart_id=?
FINEST: Caching: com.cache.dataobject.SourcePart#1
FINEST: Item was already cached: com.cache.dataobject.SourcePart#1
FINEST: Caching: com.cache.dataobject.SourcePart#2
FINEST: Item was already cached: com.cache.dataobject.SourcePart#2
FINEST: Caching: com.cache.dataobject.Part.parts#0
FINEST: Cached: com.cache.dataobject.Part.parts#0
FINEST: Invalidating: com.cache.dataobject.Part.parts#0
FINEST: Invalidating: com.cache.dataobject.Part#0
FINE: update Part set PART_NAME=? where id=?
FINEST: Invalidating: com.cache.dataobject.SourcePart#1
FINE: update SourcePart set mainPart_id=?, PART_NAME=? where id=?
FINEST: Invalidating: com.cache.dataobject.SourcePart#2
FINE: update SourcePart set mainPart_id=?, PART_NAME=? where id=?
FINEST: Updating: com.cache.dataobject.Part#0
FINEST: Updated: com.cache.dataobject.Part#0
FINEST: Updating: com.cache.dataobject.SourcePart#1
FINEST: Updated: com.cache.dataobject.SourcePart#1
FINEST: Updating: com.cache.dataobject.SourcePart#2
FINEST: Updated: com.cache.dataobject.SourcePart#2
FINEST: Releasing: com.cache.dataobject.Part.parts#0
DAO Code:
public Part addPart(Part part){
System.out.println("CALLED PERSIST");
System.out.println(this);
em.persist(part);
return part;
}
public List<Part> updateParts(List<Part> parts){
System.out.println("CALLED MULTI MERGE");
for(Part p: parts){
em.merge(p);
}
return parts;
}
Test Code:
CacheDaoRemote dao = (CacheDaoRemote) ctx.lookup("ejb/CacheDao");
List<Part> partsList = new ArrayList<Part>();
int i = 0;
Part computer = new Part();
computer.setId(i++);
computer.setName("Computer");
List<SourcePart> parts = new ArrayList<SourcePart>();
SourcePart cpu = new SourcePart();
cpu.setId(i++);
cpu.setName("CPU");
cpu.setMainPart(computer);
SourcePart monitor = new SourcePart();
monitor.setId(i++);
monitor.setName("Monitor");
monitor.setMainPart(computer);
parts.add(cpu);
parts.add(monitor);
computer.setParts(parts);
dao.addPart(computer);
partsList.add(computer);
computer.setName("HPComputer " + uniqueNumber);
cpu.setName("HPCPU "+ uniqueNumber);
monitor.setName("HPMonitor "+ uniqueNumber);
dao.updateParts(partsList);
SourcePart:
package com.cache.dataobject;
import static javax.persistence.CascadeType.ALL;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class SourcePart implements Serializable {
private int id;
private String name;
private static final long serialVersionUID = 1L;
private Part mainPart;
public SourcePart() {
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;
}
}
Part:
package com.cache.dataobject;
import static javax.persistence.CascadeType.ALL;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* Entity implementation class for Entity: Part
*
*/
@Entity
@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Part implements Serializable {
private int id;
private String name;
private static final long serialVersionUID = 1L;
private List<SourcePart> 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;
}
@OneToMany(cascade = ALL,fetch=FetchType.EAGER)
@JoinColumn(name = "mainPart_id", referencedColumnName = "id")
@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public List<SourcePart> getParts() {
return parts;
}
public void setParts(List<SourcePart> parts) {
this.parts = parts;
}
}