I am having a problem when updating/merging an entity A which has a reference to another entity B. A also has a reference to an entity C.
I create a new instance of the entity A from a domain object. Also from this domain object I use the ids to get B and C by using entityManager.getReference(<class>, <id>). I call entityManager.merge and entityManager.flush(). So far all is good, the values of both B and C are present in A. When I after the flush do a entityManager.refresh(A), the B is cleared(null), but the C is still there.
I run sql queries to verify that the value is there before the update. After the flush the FK to B is cleared, so when the refresh is called it discovers this.
I do not know what to look for here. Might it be something with how my entities are defined? Persistence-xml? Any tips are much appreciated!
EDIT:
The value of B is only cleared if I do not change the reference. If I change the reference of B to B', then it is updated correctly
The question did not show the entire context of where I was experiencing the problem. The entity A which had a reference to B, also had the foreign key field in it. This foreign key field was always null, so setting the entity reference had no effect.
Related
We use Eclipselink-2.6 with wildfly-8 server in a JavaEE7 application.
we have three JPA entities A, B, and C.
B and C extend A.
In order to change the type of an object "myObjectId" A to B, we try to:
1- Change the dtype value from "a" to "b" in Table "A" for the instance "myObjectId" using the criteria query.
2- Create a new row in the table "B" in the database for the same id "myObjectId" also with a criteria query.
3- Clearing the cache by evictAll as well Entitymanger using clear functions.
After, when I tried to find all data of type B, the object "myObjectId" came in the list but with type A!
After restarting wildfly server and call findAll, therefore, the data came with type B!
why myObjectId didn't change its type even if the first and the second level cache was cleared!?
See https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching
Essentially EclipseLink maps the JPA cache eviction call to its own invalidation logic, which seems to be keeping a reference to the object using a soft reference so that object identity is maintained. This prevents A1->B1->A1' from happening on cycles with lazy relationships.
Try calling ((JpaEntityManager)em.getDelegate()).getServerSession().getIdentityMapAccessor().initializeAllIdentityMaps() as suggested in the doc and then reading in the changed class.
I have table A and B
A like : id
name
bid
B like : id
type
in table A has a data record reference with B1,now I want update A reference with B2.
in my unitofwork if I set AutoDetectChangesEnabled = true it's work ok, but I set AutoDetectChangesEnabled = false reason is I want to up speed throw the exception like this:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property value(s) of 'GoodsKind.goods_kind_id' on one end of a relationship do not match the property value(s) of 'EnrolmentType.goods_kind' on the other end."
how cand i do?
I just had this error as well. The problem for me was that I have a complex type. When I changed the master record (let's say Person) I also wanted to change the complex type List with his contact information(s). So when I tried to save them both in one screen I got this error. Check if you fill all the ids on your screen for the master record and the complex type records. Check if they are posted to the server (if you use in example MVC). You can do this by checking the Bind statement by your MVC action.
The error says that the ID and the object specified doesn't match. This means that you are saying that A has a B with ID=2 but at the same time you have A with an object of type B with ID=5. Because you are working in a disconnected environment, EF doesn't know which one is the correct. To solve this issue you can do one of the following things:
-Get the object from EF, modify it and then save (connected environment).
OR
-Update the IDs manually (update A setting ID=5 because the object B has ID=5).
Always remember that EF tracks changes if it is in a connected environment and the tracking is enabled. If not, it has no clue of the changes you made until it tries to save it in the DB (where the object is compared with the values in the DB). One thing that you can do to manually tell EF that the entity has been modified in a disconnected environment is:
dbContext.Entry(objectA).State = EntityState.Modified;
I have an entity model which defines a One to Zero-to-one association between two entities. i.e.
A [0..1]..[1] B
A has one reference to B. B can have a reference to A.
In defining this association, I want to have the ID of 'B' within 'A'. e.g. a B_ID property. For some reason, the option to do so - 'Add foreign key properties to the 'A' entity' - is disabled. I don't know why this is, and I'm unable to figure out how to do it manually.
If anyone could help, or give me a reason for this, I'd be grateful.
I think the following article describes what you are trying to do and how to do it:
http://www.develop-one.net/blog/2011/06/29/EntityFrameworkModelFirstOnetoOneRelationship.aspx
The bit you appear to be missing (from your description) is to modify the existing 1-* relationship rather than create a new one. I am assuming you are using the designer.
I have an ERD with a main table (A) which has one attribute(String) that is a FK to another table (B).
The issue that I have is that in B the only attribute is the PK; I just want to ensure that the user inputs only one of the allowed values in the main table attribute. I do not even want to update the B table from the application, as it will be a task so unusual that I'll do it directly in the DB.
I could treat B just as another Entity and deal with them with "regular" JPA, but I am a little troubled that maybe there are more efficient ways to do it*. All I want from B table is to get the full list of values and to ensure that the attribute value is correct.
So the question is: there is a specific pattern in JPA to deal with those master tables?
Thanks In advance.
*: My concern is creating / retrieving Entity B objects when all that it is needed is an string, every time an Entity A object is created retrieved.
I would simply use a native query to get all the strings from the B table, or map B as an entity to retrieve all the B Strings using a JPQL query, but not have any association from A to B.
The B string would be stored as basic String column in entity A. And if you try creating or updating an A instance with a string that is not in the B table, then you'll get an exception at flush or commit time because the foreign key constraint is broken.
I have a OneToMany relation from A to B (A references a list Bs).
When I delete a B using either entityManager.remove(b) or a.getBs().remove(b)or both, and load A again : the deleted B will still appear in the list THOUGH it has been effectively removed from the database! I tried with and without Cascade.ALL on the relation with no success..
Thanks for your help.
You need to do both (unless you use delete orphans). If you do both it should be gone. Ensure you remove it from the correct managed a, not a detached a. Ensure the a actually contains the b to begin with.
You could always call refresh() to confirm that the database state was correct.