JPA Optimistic Lock Exception in single thread
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
add a comment |
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
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 thatmerge()
is useless (since withfind()
I am manipulating the Managed object already) andflush()
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
add a comment |
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
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
java jpa optimistic-locking
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 thatmerge()
is useless (since withfind()
I am manipulating the Managed object already) andflush()
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
add a comment |
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 thatmerge()
is useless (since withfind()
I am manipulating the Managed object already) andflush()
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 withfind()
I am manipulating the Managed object already) andflush()
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