I need to maintain entity A relationship to certain revision of #Audited entity B, so that the relationship doesn't always point to the latest version (which is the default behaviour).
Is there a framework feature (or recommended solution) for declarative approach to including the revision in the relationship?
Should this be implemented by versioning both sides of the relationship? (But that only shifts the target revision problem to the next entity in chain)
Is this a different pattern to Envers auditing?
Or is this a complete customization?
Envers is a transaction-scoped entity state snapshot auditing framework.
In short this means that any audited entity modified during a transaction will be captured in a snapshot and then stored in the audit tables. This means what you're trying to accomplish is outside the scope of the purpose behind the framework.
It's hard to offer any real suggestions as your comment about shifting the problem sounds as though you may need some form of cascading when an object graph is Entity A -> Entity B -> Entity C -> ... -> Entity n.
If you have more to share in your original post, update it and I can update my answer as well.
Related
What is the meaning of detached entity. In my course following in Spring Framework Guru. We made a DTO, Does it mean when you fetched data from db then convert it in DTO is it called Detached Entity?
A detached entity is an entity which state must not be reflected by the JPA provider.
In other words, if you change its state (i.e. through setters methods) these changes will not be saved to the underlying database, as the JPA provider doesn't have to "observe" such entities.
If entity E1 is a managed entity you can make it detached invoking (very reasonable named) method EntityManager#detach(E1). You can also use EntityManager#clear() which will clear whole PersistenceContext and effectively making all managed entities detached.
Some time ago I wrote a blog article on this general subject that helps to answer this question, and I post it here as a separate answer only because it comes at the subject from a slightly different perspective.
I use Envers 3.5 with Spring.
Lets say I have a entity A with a relation to Entity B which has a relation to Entity C.
All Entities are audited. When I change something in entity C I can see the change in that audit table. What I want is to see the change in the audittable of entity A, too. It would be ok to see that change in entity B´s table.
Can this be done with envers?
(I´m sorry for my poor English knowledge)
This is a common question about Envers, however that is not possible currently.
First of all Envers doesn't have a way to automatically know what are the roots of entity trees, that is which entities should be marked as modified upon a child-entity modification.
Secondly it would cause a lot more data to be written on each change. It would be possible to implement using some custom annotations and "marker" revisions, but I guess that task waits for a contributor :)
I'm getting a primaryKeyUpdateDisallowed ValidationException when trying to merge an entity into the database when there is an existing entity with the same primary key.
Of course, I don't get the exception when I perform a TypedQuery and have the entity manager return the entity first, update the appropriate values, and then merge. The problem is this process is too expensive, resource-wise. I need to be able to simply merge without the resulting exception.
Is there a way to structure our entity class so that we can over-write the records, including the primary keys? Or some other way around the problem?
In JPA, if you wish to do:
entityManager.merge(someEntity);
then you must first have someEntity loaded from the DB into the entityManager persistence context and then detached via "entityManager.detach(someEntity)" or by clearing the persistence context. If someEntity is not pre-loaded and detached, but is instead created via "new SomeEntity()", then the merge() function will determine that you have added a new entity and carry out an internal operation very similar to entityManager.persist(someEntity). When the data is flushed or committed in a transaction, it will generate a SQL INSERT, which will clash with the pre-existing PK.
Here's the specified behaviour from the JPA 2 spec:
The semantics of the merge operation applied to an entity X are as follows:
If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.
If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.
> The problem is this process is too expensive, resource-wise. I need to be able to simply merge without the resulting exception.
This shouldn't be the case. Retrieving the entity or list of entities from the DB should be efficient. Possibly your query could be improved. Do you have a "where" clause on the query? Do you have much cascading of entities during refresh (via attribute cascade=CascadeType.REFRESH/ALL on relationships such as #OneToMany or #ManyToOne)? Do you have a very complex inheritance hierarchy with many entities/tables? If you could provide your JPQL or criteria query, I'm sure the problem will be simple to fix. :-)
I am getting an error 3007 when I add my entity model to my solution.
I found these links:
Good explination
Short answer
About this error:
Error 1 Error 3007: Problem in Mapping
Fragments starting at lines 89, 94:
Non-Primary-Key column(s) [Person_ID]
are being mapped in both fragments to
different conceptual side properties -
data inconsistency is possible because
the corresponding conceptual side
properties can be independently
modified.
Their Answer: I agree with their conclusion that by simply deleting the Scalar Property Person_ID and leave the Navigation Property my problem is fixed. However this is not very scalable since I am dynamically building my database and my entity is updated very often. I dont want to have to go through and clean up my entity every time I update it.
My Question: Is there a way to fix the error by correcting the way EF builds the entity? Or is there a way to remove the Scalar Property through code? Perhaps there is even a few options that I am overlooking.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
My experience with EF v1 is similar to yours. When the EDM is generated incorrectly and you can't work around the issue, you have to manually edit the EDM. EF v.Next (Entity Framework v4 I believe) will support "Code Only" Entity Data Models, and the EDM designer is supposed to be much better. One or the other improvement should make our lives easier. Until then...
Does anyone know how to delete an object and all of its related entities inside of EF without manually traversing the object graph and deleting each one?
For example, I've got SalesOrder and SalesOrderDetails with a 1:N relationship between them. When I delete a SalesOrder, I want all SalesOrderDetails to be deleted automatically.
Is this possible in EF?
You should not be doing this in the Entity Framework. All popular relational databases support ON CASCADE DELETE on foreign keys which is a lot more efficient as well. I suggest you just go with that.
in this article, Alex Jamese (who post his answer), has a complete article on the topic.
Link
The EF is responsible for the correctness of the ObjectContext after SaveChanges(). So the EF attempts to synchronize the ObjectContext, with the expected database state after the expected cascade in the database.
A tell tale sign of this is that if you open up something like SqlProfiler, you will notice the EF issuing DELETE requests for dependent entities that it knows about (i.e. that are loaded in the ObjectContext) when a principal is deleted.
Essentially what is happening here is that the Entity Framework expects that deleting the principal in the database, will delete all it’s dependents in the database. So it issues, what should be, a redundant DELETE to request itself so the dependents already loaded are deleted from the ObjectContext.
The key thing to note is that the EF does not retrieve all the dependent entities and issue deletes for them: It only deletes dependents that are already in memory.