Does Envers function not work if I use JPQL? - spring-data-jpa

I'm using Hibernate Envers, but if I use JQPL grammar, can't I detect deletion?

Envers is build on the entity life cycle events and those do not get triggered when you execute modifying queries.
So yes, you are correct, things like delete myentity where something = somethingelse don't get tracked by envers.

Related

Mybatis with JPA in SpringBoot

I'm trying to use JPA (#CrudRepository), but I want to create also my custom controller with Mybatis.
I have that working, but the problem is that for example in procedures, they don't work together.
Is it possible to implement JPA with Mybatis to work together?
I've been reading a lot, I understand that Mybatis is not ORM. Some blogs indicate that it's possible, but not how.
It's possible to manage the both JPA and mybatis together under Spring Transaction. Both of them, in fact, can be rollback together within the same transaction. However, do take note of side effects such as:
e.g.
Within the same transaction:
// Perform insert and expect id to be returned
TableA tableA = new TableA();
jpaRepositoryForTableA.save( tableA );
// Use the tableA in the next mybatis mapper
TableB tableB = new TableB();
tableB.setTableAId( tableA.getId() );
this.mapper.saveTableB( tableB )
In the scenario above, TableB will not be able to get the TableA's ID.
I don't think it's good idea at all. Use one or the other.
I can imagine that you could make it working, but your can't use them on top of same tables or use transaction management for both persistence frameworks.
So if you have such use case (you didn't explain any), I would argue that your application should be split into two separate services. Optionally consider to separate your storage into two separate DB instances.

Can I use Hibernate Envers if I just want to keep deleted Entities around?

Right now we don't delete entities, but set a flag to "inactive" in the table (and filter these entities out for normal operations). Someone pointed me to Hibernate Envers, but it looks a little bit like overkill to me. My questions are:
Can we use Envers to perform our mechanism (active/inactive flag)?
If not, can Envers store a copy of a deleted entity in an archive table, but don't do any versioning / auditing stuff?
Are there lightweight alternatives for this task?
You could use Envers here, by extending the audit listener and ignoring insert/update events, however I agree that's an overkill.
Simply using an active flag with a dedicated DAO method or writing a simple Hibernate event listener should be much better suited for this task.

Correct approach to using JPA 2

I saw this link at Nabble where someone (James Sutherland) stated to someone that they were "executing a delete all JPQL query. This is basically similar to executing your own SQL, you are responsible for executing the query correctly to maintain your constraints.
This is not the normal way to delete objects in JPA. In JPA you normally read the object, then call remove() on it.".
I was wondering if this is true or not; based on how difficult it's been to remove more than simple tables, I'd start thinking this is correct.
My thoughts thus far are to do it like this:
Perform select statements, however particular they may be (e.g.
select all students where student courses > 4 and marks >= 60 and
student registration between 2011 and 2012).
Display/edit/delete
objects (so EntityManager merge/persist/remove)
Rinse, lather, and so on
Does this sound reasonable as an approach to how one is suppose to use the JPA or am I off base?
The cascading of remove was discussed here: Google App Engine - DELETE JPQL Query and Cascading. Also for instance doing batch updates won't update version column when optimistic locking is used. Thus batch updates/deletes are a bit crippled in JPA.
But I wouldn't say This is not the normal way to delete objects in JPA. When I need to delete 2, 20 or 200 objects based on some condition selecting and fetching them first just to call remove() on each is a bad idea most of the time.
After all batch updates/deletes are there in the specification for a reason.

Datanucleus JPA Update & Delete operation

I am using Datanucleus as the JPA engine to perform CRUD on an entity in Force.com DB. Insert and Select are working fine, but while updating a new row is getting created and delete does not remove the record at all. I am using following for transaction enforcement
Is there kind of an issue with the proxy object to actual object synchronization after the object has been fetched, modified and then subject to updating.
It seems that as the ORM layer (datanucleus+force sdk) is unable to match between the altered object and the original one, it is landing up creating new row.
Any help is highly appreciated.
Thanks
It would help if you can post your code. But I am guessing you might be hitting a known difference in behavior between DataNucleus and other ORMs like Hibernate.
Are you doing something like this?
MyEntity ent = new MyEntity();
ent.setId(idFromWebRequest);
ent.setXXX(valueFromWebRequest);
ent = entityManager.merge(ent);
(where the instantiation and setters might be carried out by a data binding mechanism such as Spring MVC). If you do it like this, it will not work with DataNucleus but it will work with Hibernate. For DataNucleus you must instead do:
MyEntity ent = entityManager.find(MyEntity.class, idFromWebRequest);
ent.setXXX(valueFromWebRequest);
ent = entityManager.merge(ent);
I would prefer it worked like Hibernate, but the DataNucleus team believes this is the correct behavior. Maybe they can chime in. I believe it's a matter of when you consider an entity a new entity vs. a detached entity. If your entity instance is detached, then calling merge on it should reattach it and your database row will be updated at transaction commit / flush. If it's a new instance, then the entity manager will always create a new record.
As for your delete issue, I don't know what it could be. Perhaps you can post a code sample? You can find a complete CRUD sample app using the JPA provider here:
https://github.com/forcedotcom/javasample-musiclib

Is it possible to override the ObjectContext.SaveChanges method in entity Framework?

I was wondering if it is possible to override the ObjectContext.SaveChanges() method and write our own sql logic to save the changes made to the entities in the object context instead of relying on Entity Framework to save those changes in the database.
Generally you can do anything you want if you override SaveChanges and do not call base.SaveChanges but you will loose all the stuf EF will do for you. It means you will have to manually browse metadata and map your entities to SQL tables and columns. There will be like writing half the ORM yourselves.
If you just need some little custom logic when persisting entity you can map imported stored procedure to Insert, Update and Delete operations in the entity designer.
In EF4 SaveChanges(SaveOptions) is virtual. You can override this method. MSDN
#Ladislav is correct that a stored proc is one way to do this (+1).
Another way is to write a wrapper provider.