При создании потоков с использованием интерфейса Java Callable у меня возникают проблемы, когда свойства объекта, который я обновил, не синхронизируются с базой данных, однако, когда я выполняю работу в начальном потоке, они возникают. Пример, который я создал ниже:
package peter.ford.entityupdate;
import java.util.List;
import java.util.concurrent.Callable;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
@Named
@Stateless
public class EntityUpdateBean {
@PersistenceContext(unitName="peter.ford_EntityUpdate_war_1PU")
private EntityManager em;
@Resource
ManagedExecutorService mes;
private String newName;
public String getNewName() {
return newName;
}
public void setNewName(String newName) {
this.newName = newName;
}
public void update() {
UpdateThread t = new UpdateThread();
mes.submit(t);
}
private class UpdateThread implements Callable {
@Override
public Object call() throws Exception {
TypedQuery<Widget> q = em.createQuery("select w from Widget w", Widget.class);
List<Widget> widgets = q.getResultList();
try {
for ( Widget w : widgets) {
w.setName(newName);
}
} catch (Exception e) {
}
return 1;
}
}
}
Виджет класса - это сущность:
package peter.ford.entityupdate;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Widget implements Serializable {
@Id
@Column(name="ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name="Name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Если я изменю код так, чтобы работа по поиску сущностей и последующей установке имени выполняется с помощью метода update()
EntityUpdateBean, изменения немедленно обновляются в базе данных. Кажется, что никаких ошибок не возникает, и, следуя потоку в отладчике, я вижу, что он получает список сущностей и обновляет их. нить? В данном случае это тривиальный пример, но у меня есть более крупный проект, в котором мне нужно массово обновлять объекты, одновременно проверяя данные, хранящиеся на диске для каждого из них, и wi sh, чтобы сделать это в нескольких потоках, считывающих из очередь, по соображениям производительности.