JPA Optimistic Lock Exception in single thread












1














I'm trying to update a basic deletion timestamp using a JPA persistence class. Here's the code:



    public void delete(Document document, EntityManager em, SessionContext ctx)
throws MyException {
try {
ctx.getUserTransaction().begin();
DocumentDB documentDB = em.find(WDSDocument.class, document.getId());
if (documentDB != null) {
em.lock(documentDB, LockModeType.WRITE);
documentDB.setDeletedAt(new Timestamp(System.currentTimeMillis()));
em.merge(documentDB);
em.flush(); // OptimisticLockException raised here
}
ctx.getUserTransaction().commit();
if (log.isDebugEnabled()) log.debug("DELETED " + document.getId());
} catch (Exception e) {
ctx.getUserTransaction().rollback();
throw new MyException(Utils.getError("ERR9", new String { "" + document.getId(), e.getMessage() }),
e);
}
}


The document with the same Id as document is already stored in a DB and I would like to update a single field.



The em.flush() line is raising the exception, as if another user (thread) was trying to update the same object, but this isn't the case in my application.



I've read about OptimisticLockException in JPA and I understand that it can be raised when the same user tries to update an object twice in a row, without flushing/committing to a DB first.



Apparently this error happens whenever I try to update the documentDB deletion timestamp for any object, so I guess there should be something inherently wrong with my delete() method that double updates the object itself. I was not able to troubleshoot it correctly so far.



EDITED



Here's my DocumentDB class



@Entity
@Table(name = "DOCUMENTS", schema = "WP")
public class DocumentDB extends AbstractEntity {
private static final long serialVersionUID = -98765134L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID_DOCUMENT", nullable = false)
private int id;

@Column(name = "SOURCE")
private String source = null;

@Column(name = "CREATION_DATE")
private Date creationDate;

@Column(name = "TITLE")
private String title = null;

@Column(name = "AUTHOR")
private String author = null;

@Column(name = "URL")
private String url = null;

@Column(name = "DELETED_AT")
private Timestamp deletedAt = null;

@Override
public Integer getId() {
return id;
}

@Override
public void setId(int id) {
this.id = id;
}


public Date getCreationDate() {
return creationDate;
}

public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public Timestamp getDeletedAt() {
return deletedAt;
}

public void setDeletedAt(Timestamp deletedAt) {
this.deletedAt = deletedAt;
}
}


While its abstract superclass is:



@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -98765134L;

public abstract Integer getId();
public abstract void setId(int id);

/**
* Creator of the record
*/
@Column(name = "USER_CREATION", nullable = false)
protected String userCreation;

/**
* Timestamp of creation of the record
*/
@Column(name = "DATE_CREATION", nullable = false)
protected Timestamp dateCreation;

/**
* User of the last change of the record
*/
@Column(name = "USER_LAST_CHANGE", nullable = false)
protected String userLastChange;

/**
* Timestamp of the last change of the record
*/
@Column(name = "DATE_LAST_CHANGE", nullable = false)
protected Timestamp dateLastChange;

/**
* Progressive of the variation of the record:
* used in optimistic locking of entity manager
* to avoid conflicts in insert/update
*/
@Version
@Column(name = "PG_VER_REC", nullable = false)
protected int progressiveVariationRecord;

public String getUserCreation() {
return userCreation;
}
public void setUserCreation(String userCreation) {
this.userCreation = userCreation;
}
public Timestamp getDateCreation() {
return dateCreation;
}
public void setDateCreation(Timestamp dateCreation) {
this.dateCreation = dateCreation;
}
public String getUserLastChange() {
return userLastChange;
}
public void setUserLastChange(String userLastChange) {
this.userLastChange = userLastChange;
}
public Timestamp getDateLastChange() {
return dateLastChange;
}
public void setDateLastChange(Timestamp dateLastChange) {
this.dateLastChange = dateLastChange;
}
public int getProgressiveVariationRecord() {
return progressiveVariationRecord;
}
public void setProgressiveVariationRecord(int progressiveVariationRecord) {
this.progressiveVariationRecord = progressiveVariationRecord;
}
}


Would you please provide some guidance on the next steps to perform in order to understand better this issue?



UPDATE



I haven't found the root cause of the issue so far. I suspect that my implementation of EclipseLink JPA does weird things when updating entities inside a for loop.



Unfortunately at the moment I don't have the time and the resources to dig deeper and I am using Pessimistic Locking as a workaround. Hope to find the real problem sometime in the future.










share|improve this question
























  • If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
    – Billy Frost
    Nov 23 '18 at 11:13










  • @BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
    – Ipanov
    Nov 23 '18 at 11:29










  • Why do you call merge()? It's useless. So is flush(), BTW.
    – JB Nizet
    Nov 23 '18 at 11:32










  • As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
    – Billy Frost
    Nov 23 '18 at 11:38










  • @JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
    – Ipanov
    Nov 23 '18 at 14:22


















1














I'm trying to update a basic deletion timestamp using a JPA persistence class. Here's the code:



    public void delete(Document document, EntityManager em, SessionContext ctx)
throws MyException {
try {
ctx.getUserTransaction().begin();
DocumentDB documentDB = em.find(WDSDocument.class, document.getId());
if (documentDB != null) {
em.lock(documentDB, LockModeType.WRITE);
documentDB.setDeletedAt(new Timestamp(System.currentTimeMillis()));
em.merge(documentDB);
em.flush(); // OptimisticLockException raised here
}
ctx.getUserTransaction().commit();
if (log.isDebugEnabled()) log.debug("DELETED " + document.getId());
} catch (Exception e) {
ctx.getUserTransaction().rollback();
throw new MyException(Utils.getError("ERR9", new String { "" + document.getId(), e.getMessage() }),
e);
}
}


The document with the same Id as document is already stored in a DB and I would like to update a single field.



The em.flush() line is raising the exception, as if another user (thread) was trying to update the same object, but this isn't the case in my application.



I've read about OptimisticLockException in JPA and I understand that it can be raised when the same user tries to update an object twice in a row, without flushing/committing to a DB first.



Apparently this error happens whenever I try to update the documentDB deletion timestamp for any object, so I guess there should be something inherently wrong with my delete() method that double updates the object itself. I was not able to troubleshoot it correctly so far.



EDITED



Here's my DocumentDB class



@Entity
@Table(name = "DOCUMENTS", schema = "WP")
public class DocumentDB extends AbstractEntity {
private static final long serialVersionUID = -98765134L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID_DOCUMENT", nullable = false)
private int id;

@Column(name = "SOURCE")
private String source = null;

@Column(name = "CREATION_DATE")
private Date creationDate;

@Column(name = "TITLE")
private String title = null;

@Column(name = "AUTHOR")
private String author = null;

@Column(name = "URL")
private String url = null;

@Column(name = "DELETED_AT")
private Timestamp deletedAt = null;

@Override
public Integer getId() {
return id;
}

@Override
public void setId(int id) {
this.id = id;
}


public Date getCreationDate() {
return creationDate;
}

public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public Timestamp getDeletedAt() {
return deletedAt;
}

public void setDeletedAt(Timestamp deletedAt) {
this.deletedAt = deletedAt;
}
}


While its abstract superclass is:



@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -98765134L;

public abstract Integer getId();
public abstract void setId(int id);

/**
* Creator of the record
*/
@Column(name = "USER_CREATION", nullable = false)
protected String userCreation;

/**
* Timestamp of creation of the record
*/
@Column(name = "DATE_CREATION", nullable = false)
protected Timestamp dateCreation;

/**
* User of the last change of the record
*/
@Column(name = "USER_LAST_CHANGE", nullable = false)
protected String userLastChange;

/**
* Timestamp of the last change of the record
*/
@Column(name = "DATE_LAST_CHANGE", nullable = false)
protected Timestamp dateLastChange;

/**
* Progressive of the variation of the record:
* used in optimistic locking of entity manager
* to avoid conflicts in insert/update
*/
@Version
@Column(name = "PG_VER_REC", nullable = false)
protected int progressiveVariationRecord;

public String getUserCreation() {
return userCreation;
}
public void setUserCreation(String userCreation) {
this.userCreation = userCreation;
}
public Timestamp getDateCreation() {
return dateCreation;
}
public void setDateCreation(Timestamp dateCreation) {
this.dateCreation = dateCreation;
}
public String getUserLastChange() {
return userLastChange;
}
public void setUserLastChange(String userLastChange) {
this.userLastChange = userLastChange;
}
public Timestamp getDateLastChange() {
return dateLastChange;
}
public void setDateLastChange(Timestamp dateLastChange) {
this.dateLastChange = dateLastChange;
}
public int getProgressiveVariationRecord() {
return progressiveVariationRecord;
}
public void setProgressiveVariationRecord(int progressiveVariationRecord) {
this.progressiveVariationRecord = progressiveVariationRecord;
}
}


Would you please provide some guidance on the next steps to perform in order to understand better this issue?



UPDATE



I haven't found the root cause of the issue so far. I suspect that my implementation of EclipseLink JPA does weird things when updating entities inside a for loop.



Unfortunately at the moment I don't have the time and the resources to dig deeper and I am using Pessimistic Locking as a workaround. Hope to find the real problem sometime in the future.










share|improve this question
























  • If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
    – Billy Frost
    Nov 23 '18 at 11:13










  • @BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
    – Ipanov
    Nov 23 '18 at 11:29










  • Why do you call merge()? It's useless. So is flush(), BTW.
    – JB Nizet
    Nov 23 '18 at 11:32










  • As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
    – Billy Frost
    Nov 23 '18 at 11:38










  • @JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
    – Ipanov
    Nov 23 '18 at 14:22
















1












1








1







I'm trying to update a basic deletion timestamp using a JPA persistence class. Here's the code:



    public void delete(Document document, EntityManager em, SessionContext ctx)
throws MyException {
try {
ctx.getUserTransaction().begin();
DocumentDB documentDB = em.find(WDSDocument.class, document.getId());
if (documentDB != null) {
em.lock(documentDB, LockModeType.WRITE);
documentDB.setDeletedAt(new Timestamp(System.currentTimeMillis()));
em.merge(documentDB);
em.flush(); // OptimisticLockException raised here
}
ctx.getUserTransaction().commit();
if (log.isDebugEnabled()) log.debug("DELETED " + document.getId());
} catch (Exception e) {
ctx.getUserTransaction().rollback();
throw new MyException(Utils.getError("ERR9", new String { "" + document.getId(), e.getMessage() }),
e);
}
}


The document with the same Id as document is already stored in a DB and I would like to update a single field.



The em.flush() line is raising the exception, as if another user (thread) was trying to update the same object, but this isn't the case in my application.



I've read about OptimisticLockException in JPA and I understand that it can be raised when the same user tries to update an object twice in a row, without flushing/committing to a DB first.



Apparently this error happens whenever I try to update the documentDB deletion timestamp for any object, so I guess there should be something inherently wrong with my delete() method that double updates the object itself. I was not able to troubleshoot it correctly so far.



EDITED



Here's my DocumentDB class



@Entity
@Table(name = "DOCUMENTS", schema = "WP")
public class DocumentDB extends AbstractEntity {
private static final long serialVersionUID = -98765134L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID_DOCUMENT", nullable = false)
private int id;

@Column(name = "SOURCE")
private String source = null;

@Column(name = "CREATION_DATE")
private Date creationDate;

@Column(name = "TITLE")
private String title = null;

@Column(name = "AUTHOR")
private String author = null;

@Column(name = "URL")
private String url = null;

@Column(name = "DELETED_AT")
private Timestamp deletedAt = null;

@Override
public Integer getId() {
return id;
}

@Override
public void setId(int id) {
this.id = id;
}


public Date getCreationDate() {
return creationDate;
}

public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public Timestamp getDeletedAt() {
return deletedAt;
}

public void setDeletedAt(Timestamp deletedAt) {
this.deletedAt = deletedAt;
}
}


While its abstract superclass is:



@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -98765134L;

public abstract Integer getId();
public abstract void setId(int id);

/**
* Creator of the record
*/
@Column(name = "USER_CREATION", nullable = false)
protected String userCreation;

/**
* Timestamp of creation of the record
*/
@Column(name = "DATE_CREATION", nullable = false)
protected Timestamp dateCreation;

/**
* User of the last change of the record
*/
@Column(name = "USER_LAST_CHANGE", nullable = false)
protected String userLastChange;

/**
* Timestamp of the last change of the record
*/
@Column(name = "DATE_LAST_CHANGE", nullable = false)
protected Timestamp dateLastChange;

/**
* Progressive of the variation of the record:
* used in optimistic locking of entity manager
* to avoid conflicts in insert/update
*/
@Version
@Column(name = "PG_VER_REC", nullable = false)
protected int progressiveVariationRecord;

public String getUserCreation() {
return userCreation;
}
public void setUserCreation(String userCreation) {
this.userCreation = userCreation;
}
public Timestamp getDateCreation() {
return dateCreation;
}
public void setDateCreation(Timestamp dateCreation) {
this.dateCreation = dateCreation;
}
public String getUserLastChange() {
return userLastChange;
}
public void setUserLastChange(String userLastChange) {
this.userLastChange = userLastChange;
}
public Timestamp getDateLastChange() {
return dateLastChange;
}
public void setDateLastChange(Timestamp dateLastChange) {
this.dateLastChange = dateLastChange;
}
public int getProgressiveVariationRecord() {
return progressiveVariationRecord;
}
public void setProgressiveVariationRecord(int progressiveVariationRecord) {
this.progressiveVariationRecord = progressiveVariationRecord;
}
}


Would you please provide some guidance on the next steps to perform in order to understand better this issue?



UPDATE



I haven't found the root cause of the issue so far. I suspect that my implementation of EclipseLink JPA does weird things when updating entities inside a for loop.



Unfortunately at the moment I don't have the time and the resources to dig deeper and I am using Pessimistic Locking as a workaround. Hope to find the real problem sometime in the future.










share|improve this question















I'm trying to update a basic deletion timestamp using a JPA persistence class. Here's the code:



    public void delete(Document document, EntityManager em, SessionContext ctx)
throws MyException {
try {
ctx.getUserTransaction().begin();
DocumentDB documentDB = em.find(WDSDocument.class, document.getId());
if (documentDB != null) {
em.lock(documentDB, LockModeType.WRITE);
documentDB.setDeletedAt(new Timestamp(System.currentTimeMillis()));
em.merge(documentDB);
em.flush(); // OptimisticLockException raised here
}
ctx.getUserTransaction().commit();
if (log.isDebugEnabled()) log.debug("DELETED " + document.getId());
} catch (Exception e) {
ctx.getUserTransaction().rollback();
throw new MyException(Utils.getError("ERR9", new String { "" + document.getId(), e.getMessage() }),
e);
}
}


The document with the same Id as document is already stored in a DB and I would like to update a single field.



The em.flush() line is raising the exception, as if another user (thread) was trying to update the same object, but this isn't the case in my application.



I've read about OptimisticLockException in JPA and I understand that it can be raised when the same user tries to update an object twice in a row, without flushing/committing to a DB first.



Apparently this error happens whenever I try to update the documentDB deletion timestamp for any object, so I guess there should be something inherently wrong with my delete() method that double updates the object itself. I was not able to troubleshoot it correctly so far.



EDITED



Here's my DocumentDB class



@Entity
@Table(name = "DOCUMENTS", schema = "WP")
public class DocumentDB extends AbstractEntity {
private static final long serialVersionUID = -98765134L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID_DOCUMENT", nullable = false)
private int id;

@Column(name = "SOURCE")
private String source = null;

@Column(name = "CREATION_DATE")
private Date creationDate;

@Column(name = "TITLE")
private String title = null;

@Column(name = "AUTHOR")
private String author = null;

@Column(name = "URL")
private String url = null;

@Column(name = "DELETED_AT")
private Timestamp deletedAt = null;

@Override
public Integer getId() {
return id;
}

@Override
public void setId(int id) {
this.id = id;
}


public Date getCreationDate() {
return creationDate;
}

public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public Timestamp getDeletedAt() {
return deletedAt;
}

public void setDeletedAt(Timestamp deletedAt) {
this.deletedAt = deletedAt;
}
}


While its abstract superclass is:



@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -98765134L;

public abstract Integer getId();
public abstract void setId(int id);

/**
* Creator of the record
*/
@Column(name = "USER_CREATION", nullable = false)
protected String userCreation;

/**
* Timestamp of creation of the record
*/
@Column(name = "DATE_CREATION", nullable = false)
protected Timestamp dateCreation;

/**
* User of the last change of the record
*/
@Column(name = "USER_LAST_CHANGE", nullable = false)
protected String userLastChange;

/**
* Timestamp of the last change of the record
*/
@Column(name = "DATE_LAST_CHANGE", nullable = false)
protected Timestamp dateLastChange;

/**
* Progressive of the variation of the record:
* used in optimistic locking of entity manager
* to avoid conflicts in insert/update
*/
@Version
@Column(name = "PG_VER_REC", nullable = false)
protected int progressiveVariationRecord;

public String getUserCreation() {
return userCreation;
}
public void setUserCreation(String userCreation) {
this.userCreation = userCreation;
}
public Timestamp getDateCreation() {
return dateCreation;
}
public void setDateCreation(Timestamp dateCreation) {
this.dateCreation = dateCreation;
}
public String getUserLastChange() {
return userLastChange;
}
public void setUserLastChange(String userLastChange) {
this.userLastChange = userLastChange;
}
public Timestamp getDateLastChange() {
return dateLastChange;
}
public void setDateLastChange(Timestamp dateLastChange) {
this.dateLastChange = dateLastChange;
}
public int getProgressiveVariationRecord() {
return progressiveVariationRecord;
}
public void setProgressiveVariationRecord(int progressiveVariationRecord) {
this.progressiveVariationRecord = progressiveVariationRecord;
}
}


Would you please provide some guidance on the next steps to perform in order to understand better this issue?



UPDATE



I haven't found the root cause of the issue so far. I suspect that my implementation of EclipseLink JPA does weird things when updating entities inside a for loop.



Unfortunately at the moment I don't have the time and the resources to dig deeper and I am using Pessimistic Locking as a workaround. Hope to find the real problem sometime in the future.







java jpa optimistic-locking






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 29 '18 at 15:40







Ipanov

















asked Nov 23 '18 at 10:39









IpanovIpanov

63




63












  • If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
    – Billy Frost
    Nov 23 '18 at 11:13










  • @BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
    – Ipanov
    Nov 23 '18 at 11:29










  • Why do you call merge()? It's useless. So is flush(), BTW.
    – JB Nizet
    Nov 23 '18 at 11:32










  • As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
    – Billy Frost
    Nov 23 '18 at 11:38










  • @JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
    – Ipanov
    Nov 23 '18 at 14:22




















  • If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
    – Billy Frost
    Nov 23 '18 at 11:13










  • @BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
    – Ipanov
    Nov 23 '18 at 11:29










  • Why do you call merge()? It's useless. So is flush(), BTW.
    – JB Nizet
    Nov 23 '18 at 11:32










  • As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
    – Billy Frost
    Nov 23 '18 at 11:38










  • @JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
    – Ipanov
    Nov 23 '18 at 14:22


















If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
– Billy Frost
Nov 23 '18 at 11:13




If you are "saving an object for the first time" then no, it cannot happen since there is no previous object. Define what is in the database at the point you try to UPDATE the object
– Billy Frost
Nov 23 '18 at 11:13












@BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
– Ipanov
Nov 23 '18 at 11:29




@BillyFrost thank you, I rephrased my question in order to clarify what is the DB state and what I am trying to do
– Ipanov
Nov 23 '18 at 11:29












Why do you call merge()? It's useless. So is flush(), BTW.
– JB Nizet
Nov 23 '18 at 11:32




Why do you call merge()? It's useless. So is flush(), BTW.
– JB Nizet
Nov 23 '18 at 11:32












As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
– Billy Frost
Nov 23 '18 at 11:38




As JB Nizet says, your "update" calls are pointless. That aside, post the entity itself, and then the SQL calls made by your JPA provider (in its log).
– Billy Frost
Nov 23 '18 at 11:38












@JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
– Ipanov
Nov 23 '18 at 14:22






@JBNizet I understand now that merge() is useless (since with find() I am manipulating the Managed object already) and flush() is at best redundant (commit() sends the SQL query to DB as well) if not detrimental. I'll dig deeper and find out which queries are actually executed and when.
– Ipanov
Nov 23 '18 at 14:22














0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445083%2fjpa-optimistic-lock-exception-in-single-thread%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445083%2fjpa-optimistic-lock-exception-in-single-thread%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Trompette piccolo

Slow SSRS Report in dynamic grouping and multiple parameters

Simon Yates (cyclisme)