I have a small web application; a reduced runnable version of it is below.
On every http request, I read an object, every time the same, from the database and use it to show the page's content. On the first request after publishing to Glassfish, everything is fine. However, if I change the value in the database, this change is not reflected in the next request.
Code relevant for getting the entity:
// @WebServlet MyServlet
@Inject
private MyEJB ejb;
// MyServlet.doGet()
MyEntity e = ejb.getResource(1);
System.out.printf("%s: %s%n", e, e.getValue());
// @Stateless MyEJB
@PersistenceContext
private EntityManager em;
// MyEJB.getResource()
TypedQuery<MyEntity> q = em.createNamedQuery("MyEntity.selectById", MyEntity.class);
q.setParameter("id", id);
MyEntity e = q.getSingleResult();
return e;
Changing the value to asdf!
between requests, the logging in doGet()
outputs:
Information: pkg.model.MyEntity@7bc0b80e: asdf
Information: pkg.model.MyEntity@5543a940: asdf
Apparently, the entity is cached between requests, although a different object is
returned. flush
ing the entity manager in getResource
before or after the query
did not make a difference, which I don't understand. refresh
ing the entity does
work, but is not recursive and does not cover the other needs that surely arise
in the original application. Exceptions I got while trying other things confirmed that the EntityManager is JTA-managed, as I expected.
I'm using GlassFish Server Open Source Edition 4.0 with the default EclipseLink ORM.
I think there are three options that would satisfy my needs:
- a configuration, in the Glassfish console or some WEB-INF/META-INF file or similar
- some code that I can execute before actually handling each request, making sure that objects already cached are up-to-date with the database
- a different way of injection that does this, or that limits caching to a per-request basis
How can I achieve one of these, or is it something different I actually need?
Full code below
package pkg.model;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Table(schema = "MySchema")
@NamedQueries({
@NamedQuery(name = "MyEntity.selectById",
query = "SELECT e FROM MyEntity e WHERE e.id = :id")
})
public class MyEntity {
private Long id;
private String value;
@Id
@GeneratedValue
public Long getId() {
return id;
}
@SuppressWarnings("unused")
private void setId(Long id) {
this.id = id;
}
@Basic
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package pkg;
import java.io.IOException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.servlet.ServletException;
import pkg.model.MyEntity;
@Stateless
public class MyEJB {
@PersistenceContext
private EntityManager em;
public MyEntity getResource(long id) throws ServletException, IOException {
TypedQuery<MyEntity> q = em.createNamedQuery("MyEntity.selectById", MyEntity.class);
q.setParameter("id", id);
MyEntity e = q.getSingleResult();
return e;
}
}
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pkg.model.MyEntity;
@WebServlet(name = "MyServlet", urlPatterns = "/")
public class MyServlet extends HttpServlet {
@Inject
private MyEJB ejb;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
MyEntity e = ejb.getResource(1);
System.out.printf("%s: %s%n", e, e.getValue());
resp.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = resp.getWriter();) {
out.print(e.getValue());
}
}
}
additionally, an empty beans.xml and a vanilla web.xml (just a welcome-file-list
)