When using cached entities along with optimistic locking using the @Version annotation and lazy loading a TransientObjectException may be thrown during flushing.
A test case is attached.
Entities:
{code:java}@NamedQueries({ @NamedQuery( name = "Domain.selectAll", query = "SELECT DISTINCT d" + " FROM Domain d" + " LEFT JOIN FETCH d.servers s") }) @Entity public class Domain { @Id @GeneratedValue private Long id;
@ManyToOne private Privilege privilege;
@Version private Integer rowVersion;
@OneToMany(mappedBy = "domain") private Set<Server> servers; }{code}
{code:java}@Entity public class Privilege { @Id @GeneratedValue private Long id;
@ManyToOne(fetch = FetchType.LAZY) private Domain domain;
@ManyToOne(fetch = FetchType.LAZY) private Server server;
@Version private Integer rowVersion; }{code}
{ noformat code:java }@Entity @Cacheable @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Server { @Id @GeneratedValue private Long id;
@ManyToOne private Domain domain;
@ManyToOne private Privilege privilege;
@Version private Integer rowVersion; }{ noformat code }
Code:
{code:java}@Test public void hhh123Test() throws Exception { EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin();
// Load all domains - a TransientObjectException is thrown List<Domain> domains = entityManager.createNamedQuery("Domain.selectAll", Domain.class) .getResultList();
entityManager.getTransaction().commit(); entityManager.close(); }{code} |
|