EntityManager.merge() is doing INSERTs not UPDATEs
neelixx Oct 22, 2005 6:03 PMI have noticed that I am getting duplicate records in MySQL when doing merge()'s. When I pass an entity bean to my session bean for updating, and then call EntityManager.merge(), the EntityManager is performing another INSERT.
I am running JBoss4.0.3 using MySQL Dialect.
Below, the servlet looks up the session bean, loads a Ticket (EntityBean) from the session bean, and passes Ticket to the method closeTicket().
In the session bean, I take the ticket object, modify it, then EntityManager.merge(ticket) to update the properties.
Rather than performing an UPDATE to the Ticket table, the EntityManager performs another INSERT, creating duplicate records in my DB (other than the autogenerated ID)
Is this by design? Did I miss a step?
SERVLET:
public class TestTicketManager extends ServletTestCase { InitialContext ctx; //load the session bean TicketManager ticketMgr; public static Test suite() { TestSuite testSuite = new TestSuite(); testSuite.addTestSuite(TestTicketManager.class); return testSuite; } public void setUp() { try { ctx = new InitialContext(); ticketMgr = (TicketManager)ctx.lookup(TicketManager.class.getName()); } catch (NamingException e){ e.printStackTrace(); } } public void testCreateTicket() { long id = 0; String problem = "Testing from Cactus"; id = ticketMgr.createTicket(problem); assertTrue(id>0); } public void testCloseTicket() { //load the first ticket long id = 1; //this is supposed to be an isolated test //find a way to remove the loadTicket() method. Ticket ticket = ticketMgr.loadTicket(new Long(id)); ticketMgr.closeTicket(ticket,"The printer was not plugged in."); } }
Session bean
@Stateless public class TicketBean implements TicketManager { @PersistenceContext(unitName="TechDeskEM") EntityManager em; public long createTicket(String problem) { ..... snipped ..... } public Ticket loadTicket(long ticketId) { Query query = em.createQuery("from Request req where req.class=Ticket and req.id=:id"); query.setParameter("id",new Long(ticketId)); return (Ticket) query.getSingleResult(); } public void closeTicket(Ticket ticket, String resolution) { List<Note> history = ticket.getNotes(); // Create the note closing the ticket Note note = new Note(); note.setAction(Note.ACTION_CLOSED); note.setCreated(new Date()); history.add(note); // apply the new history to the ticket ticket.setNotes(history); ticket.setResolution(resolution); ticket.setStatus(Ticket.STATUS_CLOSED); em.merge(ticket); } }
Any help would be appreciated!
--Aaron