In Spring-Hibernate project how can I use getByKey(PK key) and saveOrUpdate(Obejct object) on the same table in a same row in a single transaction - spring

Here in the following code when I invoke discoverAsync method by passing a node which is already in table, it should check that node id is exist in a table and update the other field in that row. But actually it is not happening, hiberbate is just selecting but not updating.
What my point of view is that we can not retrieve and update the same row at a same time in a same transaction. Please correct me if wrong.
Here is the code:
public Node discoverAsync(Node node) throws Exception {
if(isNodeIdEqual(node))
super.saveOrUpdate(node);
else
// TODO Raise Exception in case no node is available for discovery.
return node;
}
public boolean isNodeIdEqual(Node node){
String id = node.getId();
String retrievedId = getByKey(id).getId();
return id.equals(retrievedId);
}

You don't need to check using your method isNodeIdEqual. Hibernate's saveOrUpdate will do that for you. If the record with a particular key is not found, it will save, if it found it will update by the key

Related

Spring + Hibernate: Select from repository while it's updating an entry

I've just run into a problem, where I'm trying to select (repo.findById(id)) an object from the database using it's id, while it's being updated (Hibernate's onPreUpdate and onPostUpdate methods in PreUpdateEventListener and PostUpdateEventListener interfaces), but it's throwing a NullPointerException for me.
Perhaps it's easier if I explain it this way:
I have an object with status "PENDING", if it's being changed to "CONFIRMED", I want to check what the previous status was in the onPreUpdate method by doing this:
#Override
public boolean onPreUpdate(PreUpdateEvent preUpdateEvent)
{
final Object entity = preUpdateEvent.getEntity();
if (entity instanceof Status)
{
Status status = (Status) entity;
//Method below throws NullPointerException
Status statusFromRepo = statusRepo.findByStatusId(status.getStatusId());
}
return false;
}
But since statusRepo is already updating this object in the database, am I not able to do anything to get the object BEFORE it's updated? PreUpdateEvent contains the already "updated" version which is going to be saved in the database.

Spring Boot JPA : identifier of an instance of bingo.model.Group was altered from 1702 to null

I have a Short Question:
Last Save is working(Last Save will be Update).
But First Save is not working.(First Save will be Insert)
I can't insert this way, how is it possible?
#GetMapping(value = "/delete/{id}")
public String delete(#PathVariable BigInteger id, Model model) {
try {
Group group = groupService.findById(id);
group.setId(null);
group.isLog(true);
// This Save will be Insert Data
groupService.save(group);
group = groupService.findById(id);
group.isLog(true);
//This Save will be Update Data
groupService.save(group);
return "redirect:/accountsGroup/";
} catch (Exception ex) {
return "masters/accountsInfo/groups/index";
}
}
You can't just set the ID null.
The entity is in a managed state and will not be new just because you set the ID to null.
The proper way would be to clone the entity state in a new instance.
You could also try to detach the entity (EntityManager.detach) and then set the ID to null. Maybe it will insert a new row. But as I said this is not the way you should do that.
Read more about entity states here: https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/

MVC3 Entity Framework Code First Updating Subset Related List of Items

I have a table of data with a list of key value pairs in it.
Key Value
--------------------
ElementName PrimaryEmail
Email someemail#gmail.ca
Value Content/Images/logo-here.jpg
I am able to generate new items on my client webpage. When, I create a new row on the client and save it to the server by executing the following code the item saves to the database as expected.
public ViewResult Add(CardElement cardElement)
{
db.Entry(obj).State = EntityState.Added;
db.SaveChange();
return Json(obj);
}
Now, when I want to delete my objects by sending another ajax request I get a failure.
public void Delete(CardElement[] cardElements)
{
foreach (var cardElement in cardElements)
{
db.Entry(cardElement).State = EntityState.Deleted;
}
db.SaveChanges();
}
This results in the following error.
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
I have tried other ways of deleting including find by id remove and attach and delete but obviously I am approaching in the right fashion.
I am not sure what is causing your issue, but I tend to structure my deletes as follows:
public void Delete(CardElement[] cardElements)
{
foreach (var cardElement in cardElements)
{
var element = db.Table.Where(x => x.ID == cardElement.ID).FirstOrDefault();
if(element != null)
db.DeleteObject(element);
}
db.SaveChanges();
}
although I tend to do database first development, which may change things slightly.
EDIT: the error you are receiving states that no rows were updated. When you pass an object to a view, then pass it back to the controller, this tends to break the link between the object and the data store. That is why I prefer to look up the object first based on its ID, so that I have an object that is still linked to the data store.

#UniqueConstraints failing on update

I have an Entity class in which I put uniqueconstraint annotation
#Table(uniqueConstraints={#UniqueConstraint(columnNames={"staffRecord_id", "defaultLabel_id","company_id","keyCode"})})
public class AllowanceDeduction implements Serializable{
---
What I have noticed that is when I try to save on the table
using
if (allowanceDeduction.getId() == null) {
this.entityManager.persist(allowanceDeduction);
} else {
this.entityManager.merge(allowanceDeduction);
}
when the save or update fails due to a unique constraint. Isn't it only supposed to fail when trying to save a new record that is identical to a record that already exist.
Why would it fail when trying to merge or update?
Please help needed
I can't say for sure but it looks like you're trying to persist a null id
if (allowanceDeduction.getId() == null) {
this.entityManager.persist(allowanceDeduction);
/* don't you need the id set to a non-null value in order to persist it? */
} else {

Linq to SQL Update - NullReferenceException on update following Detach

I can't currently understand why my update method in my repository for the style entity is throwing a NullReferenceException in my Linq to SQL domain model layer. The problem seems to be that the EntitySet<Product> Product property on the Style object that I am updating is null following the necessary use of a Detach method. The actual exception is thrown on the attach prior to the submission of changes.
My update is only meant to target the Style table, the Product reference should not really come into it, but the relationship is mapped in the code generated by SQLMetal, which is an important part of my application design.
If I delete the foreign key relationship, recreate the mapping class and adjust code accordingly, the problem goes away. I would however like to kep the forign key relationship if possible.
I will attempt to best explain the set up:
The relationship in the SQL server database is like so, with the Product table referencing the Style table:
The entity mapping class is created with SQLMetal, as far as I know, there is nothing unusual in the way this is generated.
The update method is:
public Style Update(Style style)
{
using (var dc = new ProjectERPDataContext(Config.ConnectionStringERPDB))
{
style.Detach();
dc.Style.Attach(style);
dc.Refresh(RefreshMode.KeepCurrentValues, style);
dc.SubmitChanges();
return style;
}
}
The detach method is kept in a partial class:
The detach method exists because without, the exception is thrown: "An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported."
public partial class Style
{
public void DetachEntityRefs()
{
this._Product = default(EntitySet<Product>);
}
}
The entity class starts like:
[Table(Name="dbo.Style")]
public partial class Style : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _ID;
private string _Name;
private EntitySet<Product> _Product;
So you can see exactly where the exception is thrown:
Full stack trace:
System.NullReferenceException : Object reference not set to an instance of an object.
at System.Data.Linq.Mapping.EntitySetDefSourceAccessor`2.GetValue(T instance)
at System.Data.Linq.Mapping.MetaAccessor`2.GetBoxedValue(Object instance)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.HasDeferredLoader(MetaDataMember deferredMember)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.get_HasDeferredLoaders()
at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(MetaType mt, Object obj, Dictionary`2 visited, Boolean recurse, Int32 level)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(Object obj, Boolean recurse)
at System.Data.Linq.Table`1.Attach(TEntity entity, Boolean asModified)
at ProjectERP.DomainModel.Repositories.SQLStyleRepo.Update(Style style) in SQLStyleRepo.cs: line 45
at ProjectERP.UnitTests.DomainModel.SQLStyleRepoTests.Test_can_update_style() in SQLStyleRepoTests.cs: line 67
I bet the cause is this timebomb you planted here:
this._Product = default(EntitySet<Product>);
default(EntitySet<Product>) is null. Try setting it to something:
this._Product = new EntitySet<Product>();

Resources