EJB3 EntityManager.setFlushMode() behavior
I'm trying to test out the FlushModeType behaviour of the Entity Manager. I'm working from the oreilly book "Enterprise JavaBeans 3.0", and even though the examples work in the book perfectly, whenever I try to setup my own examples, the behavior seems to be different.
The code below is commented to explain the problem step by step. But the last step (updating of the last name) does not work as expected. Can anyone explain what I am doing wrong?
Thanks in advance
Person Entity:
-
package com.monkeyinabucket.ejb3.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
@SuppressWarnings("serial")
@Entity
publicclass Personimplements java.io.Serializable{
privateint id;
private String firstName;
private String lastName;
public Person (){
}
public Person (int id, String firstName, String lastName){
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
@Id
publicint getId(){
return id;
}
publicvoid setId(int id){
this.id = id;
}
public String getFirstName(){
return firstName;
}
publicvoid setFirstName(String firstName){
this.firstName = firstName;
}
public String getLastName(){
return lastName;
}
publicvoid setLastName(String lastName){
this.lastName = lastName;
}
public String toString (){
return firstName +" " + lastName;
}
}
Stateless Bean:
-
package com.monkeyinabucket.ejb3.agent;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import java.lang.StringBuffer;
import java.lang.Math;
import com.monkeyinabucket.ejb3.domain.Person;
@Stateless
publicclass HumanResourceAgentBean
implements HumanResourceAgentRemote{
@PersistenceUnit(unitName ="monkeyinabucket")
private EntityManagerFactory factory;
private EntityManager manager1;
private EntityManager manager2;
publicvoid demoFlushMode(){
// Using 2 EntityManagers. Each has its own 'persistence context', so
// each will not see the changes made by the other until it is
// 'flushed'
manager1 = factory.createEntityManager();
manager2 = factory.createEntityManager();
try{
System.out.print(
"--\n"
+"| manager1|manager2 |\n"
+"--\n"
+"\n"
);
Person person =new Person(1,"Kerri","Vicknair");
manager1.persist(person);
showManagerViews (
"After:\n"
+"Person person = "
+"new Person(1, \"Kerri\", \"Vicknair\");\n"
+"manager1.persist(person);"
);
// This 'correlated query' will cause a flush to" occur on manager1
// because it's FlushModeType is AUTO
// NOTE: persist(), merge(), remove(), find() or getReference() do
// not cause a flush
manager1.createQuery("FROM Person WHERE id = 1").getSingleResult();
showManagerViews (
"After:\n"
+"manager1.createQuery(\"FROM Person WHERE id = 1\""
+").getSingleResult();"
);
person.setLastName("Tyler");
showManagerViews ("After:\nperson.setLastName(\"Tyler\")");
// I would expect this to cause the name change to be visible to
// manager2. But it does not...
// According to 'Enterprise JavaBeans 3.0' page p.560 it *should*
// have!
manager1.flush();
showManagerViews (
"After:\n"
+"manager1.flush()"
);
}finally{
manager1.close();
manager2.close();
}
}
publicvoid showManagerViews (String message){
Person person1 = manager1.find(Person.class, 1);
Person person2 = manager2.find(Person.class, 1);
String person1Name;
String person2Name;
if (person1 ==null){
person1Name ="null";
}else{
person1Name = person1.toString();
}
if (person2 ==null){
person2Name ="null";
}else{
person2Name = person2.toString();
}
System.out.print(
message +"\n"
+"--\n"
+"|" + padName(person1Name)
+"|" + padName(person2Name) +"|\n"
+"--\n"
);
}
public String padName(String name){
double pad = (25.0 - name.length()) / 2.0;
StringBuffer paddedName =new StringBuffer();
double leftPad = Math.floor(pad);
for (int i = 0; i < leftPad; ++i){
paddedName.append(" ");
}
paddedName.append(name);
double rightPad = Math.ceil(pad);
for (int i = 0; i < rightPad; ++i){
paddedName.append(" ");
}
return paddedName.toString();
}
}
Stateless Bean Remote:
package com.monkeyinabucket.ejb3.agent;
import javax.ejb.Remote;
@Remote
publicinterface HumanResourceAgentRemote{
publicvoid demoFlushMode();
}

