I am somewhat new to using JPA -- I'll put that out there right off the bat. I'm getting more familiar with it, but there are big holes in my knowledge right now.
I am working on an application that uses JPA, and deletes entities using the EntityManager.remove(Object entity) function. However, the application also links into a third-party application, and I would like to add logic that gets executed whenever a certain type of Entity is removed from the persistence layer.
My question is this. Is there a way to add logic to the EntityManager.remove(Object entity) function on a Entity class level, such that every time that type of entity is deleted the extra logic is executed?
Thanks much.
Entity class may have methods annotated with #PreRemove or #PostRemove.
If you are using Eclipselink, it has a much more fine grained native event system via the DescriptorEventListener interface.
Related
the Topic already says one of the key roles regarding ORM
Don't run your own ORM Implementation
But, I have a situation here where I'm not sure how to get our Requirements implemented properly.
To give you a bit of background, currently we are using Spring Data JPA with Hibernate as JPA Implementation and all is fine so far.
But we have separate fields which we want to "manage" automatically, a bit similar to Auditing Annotations from Hibernate (#CreatedBy, #ModifiedBy, ...).
In our case this is e.g. a specific "instance" the entity belongs to.
Our Application is rather a Framework than an App, so other Developers frequently add Entities and we want to keep it simple and intuitive.
But, we do not only want to set it automatically on storage but also add it as condition for most "simple and frequent" queries (see my related question here Inject further query conditions / inject automatic entity field values when using Spring Data JPA Repositories).
Thus, I thought about building a simple Layer on top of the EntityManager and its Criteria API to support at least simple Queries like
findById(xx)
findByStringAttribute(String attribute, String value)
findByIntegerAttribute(int attribute, String value)
...
I'm not sure if this is too broad of a question but, what are your thoughts on that? Is this a reasonable idea or should I skip that idea?
My application has about 50 entities that are displayed in grid format in the UI. All 50 entities have CRUD operations. Most of the operations have the standard flow
ie. for get, read entities from repository, convert to DTO and return a list of DTO's.
for create/update/delete - get DTO's - convert to entities, use repository to create/update/delete on DB, return updated DTOs
Mind you that for SOME entities, there are also some entity specific operations that have to be done.
Currently, we have a get/create/update/delete method for all our entities like
getProducts
createProducts
updateProducts
getCustomers
createCustomers
updateCustomers
in each of these methods, we use the Product/Customer repository to perform the CRUD operation AFTER conversion from entity -> dto and vice versa.
I feel there is a lot of code repetition and there must be a way by which we can remove so many of these methods.
Can i use some pattern (COMMAND PATTERN) to get away with code repetition?
Have a look at the Spring Data JPA or here project. It does away with boilerplate code for DAO.
I believe it basically uses AOP to interpret calls like
findByNameandpassword (String name,String passwd)
to do a query based upon the parameters passed in selecting the fields in the method name (only an interface).
Being a spring project it has very minimal requirements for spring libraries.
Basically, you have 2 ways to do this.
First way: Code generation
Write a class that can generate the code given a database schema.
Note that this you will create basic classes for each entity.
If you have custom code (code specific to certain entities) you can put that in subclasses so that it doesn't get overwritten when you regenerate the basic classes.
Object instatiation should be via Factory methods so that the correct subclass is used.
Make sure you add comments in the generated code that clearly states that the code is generated automatically (so that people don't start editing them directly).
Second way: Reflection
This solution, while being more elegant, is also more complex.
Instead of generating one basic class for each entity you have one basic class that can handle any entity. The class would be using reflection to access the DTO:s.
If you have custom code (code specific to certain entities) you can put that in other classes. These other classes would be injected into the generic class.
Using reflection would require a strict naming policy on your DTO:s.
Conclusion
I have been in a project using the first method in a migration project to generate DTO classes for the service interface between the new application server (running java) and the fat clients and it worked quite well. We had more than 100 generated DTO classes. I am aware that what you are attempting is slighty different. Editing database records is a generic problem (all projects need it) but there aren't (m)any frameworks for it.
I have been thinking about creating a generic tool or framework for it but I have never gotten around to it.
I'm building an application using JPA 2.0 (Hibernate implementation), Spring, and Wicket. Everything works, but I'm concerned that my form behaviour is based around side effects.
As a first step, I'm using the OpenEntityManagerInViewFilter. My domain objects are fetched by a LoadableDetachableModel which performs entityManager.find() in its load method. In my forms, I wrap a CompoundPropertyModel around this model to bind the data fields.
My concern is the form submit actions. Currently my form submits pass the result of form.getModelObject() into a service method annotated with #Transactional. Because the entity inside the model is still attached to the entity manager, the #Transactional annotation is sufficient to commit the changes.
This is fine, until I have multiple forms that operate on the same entity, each of which changes a subset of the fields. And yes, they may be accessed simultaneously. I've thought of a few options, but I'd like to know any ideas I've missed and recommendations on managing this for long-term maintainability:
Fragment my entity into sub-components corresponding to the edit forms, and create a master entity linking these together into a #OneToOne relationship. Causes an ugly table design, and makes it hard to change forms later.
Detach the entity immediately it's loaded by the LoadableDetachableModel, and manually merge the correct fields in the service layer. Hard to manage lazy loading, may need specialised versions of the model for each form to ensure correct sub-entities are loaded.
Clone the entity into a local copy when creating the model for the form, then manually merge the correct fields in the service layer. Requires implementation of a lot of copy constructors / clone methods.
Use Hibernate's dynamicUpdate option to only update changed fields of the entity. Causes non-standard JPA behaviour throughout the application. Not visible in the affected code, and causes a strong tie to Hibernate implementation.
EDIT
The obvious solution is to lock the entity (i.e. row) when you load it for form binding. This would ensure that the lock-owning request reads/binds/writes cleanly, with no concurrent writes taking place in the background. It's not ideal, so you'd need to weigh up the potential performance issues (level of concurrent writes).
Beyond that, assuming you're happy with "last write wins" on your property sub-groups, then Hibernate's 'dynamicUpdate' would seem like the most sensible solution, unless your thinking of switching ORMs anytime soon. I find it strange that JPA seemingly doesn't offer anything that allows you to only update the dirty fields, and find it likely that it will in the future.
Additional (my original answer)
Orthogonal to this is how to ensure you have a transaction open when when your Model loads an entity for form binding. The concern being that the entities properties are updated at that point and outside of transaction this leaves a JPA entity in an uncertain state.
The obvious answer, as Adrian says in his comment, is to use a traditional transaction-per-request filter. This guarantees that all operations within the request occur in single transaction. It will, however, definitely use a DB connection on every request.
There's a more elegant solution, with code, here. The technique is to lazily instantiate the entitymanager and begin the transaction only when required (i.e. when the first EntityModel.getObject() call happens). If there is a transaction open at the end of the request cycle, it is committed. The benefit of this is that there are never any wasted DB connections.
The implementation given uses the wicket RequestCycle object (note this is slightly different in v1.5 onwards), but the whole implementation is in fact fairly general, so and you could use it (for example) outwith wicket via a servlet Filter.
After some experiments I've come up with an answer. Thanks to #artbristol, who pointed me in the right direction.
I have set a rule in my architecture: DAO save methods must only be called to save detached entities. If the entity is attached, the DAO throws an IllegalStateException. This helped track down any code that was modifying entities outside a transaction.
Next, I modified my LoadableDetachableModel to have two variants. The classic variant, for use in read-only data views, returns the entity from JPA, which will support lazy loading. The second variant, for use in form binding, uses Dozer to create a local copy.
I have extended my base DAO to have two save variants. One saves the entire object using merge, and the other uses Apache Beanutils to copy a list of properties.
This at least avoids repetitive code. The downsides are the requirement to configure Dozer so that it doesn't pull in the entire database by following lazy loaded references, and having yet more code that refers to properties by name, throwing away type safety.
I want to achieve basic CRUD operations available of the db schema I already have for a JAVA program. To put it in another way, I have a DB schema I use with PHP and I just need them to be entities available in a JAVA application. I discovered I can use Netbeans and sucessfully created Entities from DB!
(Entities look like this: http://pastebin.com/f601b9218)
However when I try to create New > JPA controllers from entity classes in Netbeans I got empty JPA controller classes like:
package javaapplication3;
public class CustomerJpaController {
}
It is empty :) I was expecting CRUD functions inside the generated JPA controller classes as I read from examples and tutorials.
What could be the reason of empty JPA controller classes? Is there any other easy way for me to "just" match DB tables with JAVA classes for basic CRUD operation. (I wish there could be easy way to achieve active record pattern)
Thanks in advance.
Usually, I never like to go too much with the wizard thing. But it seems like it should generate the basic CRUD operations, though. I don't know exactly which tutorial you followed. Right now, I am looking at this. After reading this I am getting the same impression, by the way. But may be it just generates the empty classes, and nothing else. I am not sure never tried to do that.
However, coding it yourself would be quite simple, I believe. Especially when you already got the NamedQueries defined for your entities.
Currently we are testing out entity classes and "worker" classes by writing java servlets for each entity and doing Insert,update,delete,find... for each entity to ensure that it works. The worker classes are simply implementations of an interface that persists the entity to the database using JDBC, they do the DB work for the entity.
What I'm wondering is, what is the best way to test entity classes in Java?
I'm looking for an automated approach rather than writing, basically, a mock application that calls all of the functions that I'm trying to test for each new entity that is created.
You should be able to set-up and use entity and "worker" (as you put it) classes independently or servlets and a Web container.
With pure JDBC and JUnit, you would typically do the following:
Open a JDBC connection in TestCase constructor.
Begin a transaction on setUp().
Rollback a transaction on tearDown().
Use the actual entity instances in the particular testXxx() methods.
In this approach, you would be having one, possibly local, database instance per developer. For something more advanced, consider DbUnit.
One option would be to use reflection to find the different pieces of the entities (i.e. different fields) and then have the method call save, update, delete, etc using those different entities. Then, when you added a new entity, if your setup is done using xml or something similar, the test will just pick them up.
I am speaking from a Hibernate user perspective, so this may not be entirely applicable to your situation, but it has worked well for me in the past.