Beans: How to properly manage a property affected by another one - java

I have an Entity/JSF Managed Bean Ticket that represents a helpdesk
ticket.
It has a status property; when the status is set to closed I want to
change the value of the closingDate property to the current system time.
But I think that code should be contained in the bean, as each time the
ticket is closed the time should be recorded.
What would be the proper way to manage it? I have several ideas.
Make setter of creationTime private, and change its value when the
status setter is called. Fast and quick, but makes a setter change two
attributes. Also, forces me to use JPA field access (not much of a problem
as I am already using it, but still a limitation) and I am not clear of
what will happen when the bean is serialized.
Make the status property a bound property as described in JavaBeans,
and make the class a PropertyChangeListener to itself. Very formal, but
a little overcomplicated to my likening.
Make setters for both properties private, and add a non-bean method
close() that performs both actions. I would go this way but it can make
me it complicated to work with JSF.
Do nothing. Keep the bean as dumb as it can and move the logic to the
controller; cross my fingers hoping that nobody forgets to update both
attributes.
I favour 1) or 3), but I would like to know if there is a better approach.

I don't know if anyone can tell you the proper way to manage it, as arguments can be made for many different approaches just like you make them. To add to your list as a combination of 1) and 3), for example:
Have the setter of status update creationTime when it status is set to closed and leave both setters public. Has benefits from both as I'm not aware of any downside to this from a JPA perspective.
What I would advice against however is having a Entity/JSF Managed Bean. I would recommend having two, an Entity bean and a JSF Managed Bean. This way your Entity bean can be kept as dumb as it can be, while your JSF Managed Bean will have smart methods like close() or reopen() and comprised of a series of dumb calls to the Entity bean. Also, you can do things like persist() in #PreDestroy. Easy to develop, easy to maintain, easy to make decisions. Hopefully you'll find this helpful.

Related

Spring: Scoped fields

I wrote this idea on the Spring JIRA and even though I know this is not a key feature and has minor priority, I'd still expect some answer by now. I publicize the idea, because I want to know what you guys think about it, if it's cool and I should implement it myself, or is the need for this is a sign of bad architecture.
So the idea itself is - as the title suggests - is a field in a Spring Bean, which has a different scope then the bean itself. We already have something like this, in the shape of scoped proxies, however it works only for bean dependencies. I might want to store a list of Strings of session scope in a bean of singleton scope. I, then have to create a new bean, with scope of session for one field and some functions to use that field. It seems a waste of code and I'd find it bad, because I wouldn't be able to use that bean anywhere else, because it'd already have that data the first class put into it.
I could rephrase the mess above and say that I want to have named beans with arbitrary type (so not necessarily spring beans) and on top of the scope we configure it to have, that field would also be different for every instance of the parent class.
This could make a field instance broader than a prototype scoped bean, but also less broad then the actual scope we'd like to use it in. Kind of a middle ground.
Here is the JIRA issue I wrote: https://jira.spring.io/browse/SPR-16971
In my understanding, Scopes only work with Dependency Injection as it's the DI Container that decides if it should return a new instance or an already existing one. So everything that is #Autowired can be scoped.
I can't imagine how scoping a normal field would work. If I change it, should it change in all other objects that "use" it? I would have to be some kind of proxy object then and neve a primivive value. If on the other hand you have a proxy object, why not use the currently available autowire mechanism.

Hibernate - Centralized entity instantiation

I have some old code that basically uses singleton services inside entities to perform some tasks, and to start cleaning up thinks, I want to inject those services on entities, so at least I can break that hard dependencies for now.
I'm trying to find some place in Hibernate where I can control entities instantiation, by now I've found some possible hooks, like:
- org.hibernate.tuple.Instantiator
- org.hibernate.Interceptor
I need to control that instantiation when an object is first loaded from database, as well as when it's loaded from cache... Also, maybe a global PreLoadEvent may help, I just need to make sure that when an object is returned from Hibernate, it has all it's (service) dependencies injected (spring is already here).
Can someone please point me to where to continue the search?
You could use #Configurable annotation,
see this blog post for more info.
Well, after some testing, an instance of org.hibernate.event.PreLoadEventListener does the trick.
It gets called always, no matter where the instance came from. This way I'm not controlling instantiation, but at least I have a place to inject dependencies befor the instance is returned to client code.
Thanks all for your time!

How to control JPA persistence in Wicket forms?

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.

Using stateless EJB beans in an Entity Bean

Obviously using stateless EJB beans in an entity bean smells, but please consider a scenario as follows and tell me if you know of a better solution:
I have an InvoiceTemplate Entity Bean with field NextInvoiceDate
Generating NextInvoiceDate is a complex procedure and should be performed outside of the InvoiceTemplate class
NextInvoiceDate should be updated each time InvoiceTemplate is stored to the db
For now I have logic regarding the generation of NextInvoiceDate in #PrePersist #PreUpdate methon in InvoiceTemplate entity bean. The logic is getting more and more complicated and I want to move it outside of the InvoiceTemplate entity bean. It looks to me that there should be a service to calculate NextInvoiceDate. But then is it right to invoke this service from the inside of InvoiceTemplate?
It isn't such a smell - it is a lean towards domain-driven design.
I don't know of any way to do this automatically, but you can:
in the session beans where you handle your Invoicetemplate, inject the helper bean that has the logic to calculate the next date
create a private field with a setter on the entity, and before you start using it call entity.setNextDateHelper(..)
You can also check whether AspectJ doesn't offer some EJB options so that you can inject the EJB whenever an entity of a given type (InvoiceTemplate) is created. AspectJ works like that with spring beans, I don't know whether there are such options for EJB.
Do you need anything as complicated as a service or EJB? Can you just write a static method (possibly on a utility class) to hold the logic? Normally I'm pretty biased against this sort of thing, but if all you've got is some complex logic that doesn't require any DB interaction or a lot of object collaboration, it may be the cleanest approach.

How to know what made a hibernate persisted object dirty?

An object I mapped with hibernate has strange behavior. In order to know why the object behaves strangely, I need to know what makes that object dirty. Can somebody help and give me a hint?
The object is a Java class in a Java/Spring context. So I would prefer an answer targetting the Java platform.
Edit: I would like to gain access to the Hibernate dirty state and how it changes on an object attached to a session. I don't know how a piece of code would help.
As for the actual problem: inside a transaction managed by a Spring TransactionManager I do some (read) queries on Objects and without doing an explicit save on these Objects they are saved by the TransactionManager because Hibernate thinks that some of these (and not all) are dirty. Now I need to know why Hibernate thinks those Objects are dirty.
I would use an interceptor. The onFlushDirty method gets the current and previous state so you can compare them. Implement the Interceptor interface and extend EmptyInterceptor, overriding onFlushDirty. Then add an instance of that class using configuration.setInterceptor (Spring may require you to do this differently). You can also add an interceptor to the session rather than at startup.
Here is the documentation on interceptors.
create a Test Case or similar, so you can reproduce the problem with a single click.
enable logging for org.hibernate check the logging for the string "dirty" (actually you don't need all of org.hibernate, but I don't know the exact logger.
Find to spots in the program, one where the entity is not dirty, one where it is dirty. Find the middle of the code between the two points, and put a logging statement there, for logging the isdirty Value. Continue with the strategy until you have reduced the code to a single line.
Check out the hibernate code. Find the code that does the dirty checking. Use a debugger to step through it.
Assuming that the state of the object cannot be accessed directly (e.g. no public or package protected fields) and is not fiddled with by reflection, you can put a breakpoint at the start of all of the object's methods and run through the scenario that makes the object dirty in the debugger.

Categories