I've been using binding frameworks for a while now and i'd like to know how you handle this cases.
You have a newspaper that has some attributes like
(String) headline
(Boolean) published
(Date) publishmentDate
On your view, you have a list of newspapers, than can be edited all in the same time. This means you can change the headlines of all newspapes, or all their state "published" in a single request.
The matter is that, as we are using a binding framework, you will edit the newspapers' data a bit like if you were editing the data in a DB... binding each value to a field, independently from each others.
But... what i'd like to do is that when i publish a newspaper, the publishmentDate is updated to the current date.
I could for sure put a publishmentDate field on the form, or even a hidden field setted to the current date... But this is neither clean or secure.
I think it's better to have an action publish() that will set the flag to true, but also update the publishmentDate (and other logic if needed...)
I just wonder how do you handle that?
I've seen and thought about different approaches:
1) Sometimes we bind the new parameters to an existing persistent ORM entity.
This means we retrieve the entity just before the binding, so that we bind the values to an existing, "already filled" entity object. This is sometimes called "hydrating the entity"
Thus the only way to know if you have to launch a "publish action" is by comparing the old field with the new one, so that you know if it was edited and in which direction (false->true = publish)
It's possible to use an ORM listener, (like #PostLoad, a Hibernate Interceptor/EventListener or anything else) so that you keep these "before binding" values you need.
This works nice but it's quite "weird" to launch a publish action on the vehicle, while the binding already set the published flag to true.
2) It's possible to do nearly the same thing but to use another flag... for exemple a flag that represents the user wish to publish a newspaper.
Thus you don't have to compare with the previous value, you just check if the user wish to publish a newspaper and then launch the action... (and the real published flag was still = false when you launched the action this time...)
The matter is that as you are using a binding framework, you want the published checkbox to be checked on your view for newspapers that have already been published.
So if the attribute for binding is now published_wish, you'll have to set it a value or all your checkboxes will always be unchecked...
This means that you'll have, before showing the view, do something like published_wish = published
Most times the wish flag will not be persisted, but i've seen some cases where the "wish" MUST BE persisted, thus no need to do published_wish = published
3) Use an empty non persisted entity for the binding, then recopy the values of this non persisted entity to the real persisted object.
So when you recopy the values from one object to the other, you can launch any action you want, customize everything...
But it's a bit heavy to have to recopy all these parameters...
There may be other ways to do...
How would you do that? So that it doesn't just work well, but it is also elegant, maintenable... i don't see any perfect solution here
I agree with you and I would also use a Publish button in this case (with possibly an "Unpublish" button as well), allowing the user to select multiple articles and publish them all at once. I wouldn't allow the user to edit the Published checkbox and the publication date directly.
The question did not open me very well, but if the case is that you want to elegantly save publish dates, why don't you leave database to do it for you. On Mysql you have example here where the database saves the lastChanged data automatically for user.
Also database triggers may make sence for you. At least I see automatical exact database queries better solution than a bunch of hacks inside the code making those things.
I do hope these answered your question or even the right question in mind.
Related
I have defined a class which acts like a model/pojo. The class has many keys/variable. I have implemented custom solution for storing the POJO on disk for future uses. Now what I want to do is that whenever any value in the class/POJO is changed, I should call a method which sync the fresh changes with file on disk.
I know I can define setter for each variable. But it's quite tedious to do for 100s of direct and sub fields, and even if I define setter for each field, I have to call sync function from all the setters.
What I need is single proxy setter or interceptor for all change pushes to variables in class.
I am using this in an android application, so whenever the user enters new details in his/her account I have to store those details at that specific instance of time for preventing the data loss. I am using GSON for serialising and de-serialising.
Sorry for using vague terminologies, never been to college :|.
The easiest solution is indeed to use a setter. You only have to create one for each field you want to monitor, and most IDEs generate them for you or you can use something like Koloboke, so it being tedious isn't really an argument.
A proxy class or reflection would also be possible, but that is pretty hacky. Another way would be an asynchronous watcher/worker that checks for changes in you POJO instances, but even that seems unnecessarily complicated.
Apart from that you might need to rethink your POJOs structure if it has that many fields.
The problem with persisting(in your case writting to a disk) entity on each property update is that most of the updates are modifying more then one property. So in case you have a code like this:
entity.setA(avalue);
entity.setb(bvalue);
entity.setc(cvalue);
You would write it to the disk 3 times, which is probably not a best way, as it takes more resources, and 2 out of 3 writes are unnecessary.
There are several ways to deal with it. Imagine you have some service for saving this data to a disk, lets name it entityRepository. So one option is manually call this entityRepository each time you want to save/update your entity. It seems to be very uncomfortable, comparing to calling this automatically on setter call, however, this approach clearly shows you when and why your entity is persisted/updated, in your approach it's unclear, and can lead to some problems future problems and mistakes, for example, in future you will decide that you now need to update one of the properties without immideately persisting, then it appears that you will need 2 setter, one with update, and one without...
Another way is to add version property, and when its setter is called inside this setter call entityRepository.save(this).
The other way is to look at AOP, however anyway I don't recommend persist entity on any change, without having control over it.
You are talking about data binding. There is no built-in way for that so you have indeed to sync it yourself. Look into How to Write a Property Change Listener. There are also lots of other approaches to this, but as said no built-in way.
I need to prevent the situation where either
1. Two different JSESSIONID's exist for the same user account or,
2. Two tabs of a single browser reference the same JSESSIONID.
Any suggestions? If an existing session is detected, the user can either:
a) Quit the second attempt
b) Kill the existing session (an assassin!) and start a new session.
The preference is for a sever-side solution. That is, I don't want to depend on user's turning cookies off which forces the JSESSIONID into the URL.
Embeding a hidden input field with a unique token in each page sounds like the only solution for a problem like this. This seems to be like the only way to tell one tab from another, even if they're the exact same URL.
Keep in mind though, that what you're doing seems like pretty bad practice; any particular reason to prevent the user from using more than one tab?
Part 1 could be done using a singleton pattern that checks current sessionid for the user against a map of user-SID.
Part 2, which could be understood in transactional webapps where you need to ensure that the user reads the correct info (instead of having a one tab with old values and one tab with newer values- scenario)... it could use the same sessionid map, injecting it in the dom and validate it using javascript.
EDIT. Part 2 validation could be done better in a filter against the map of client-sessionid. And a correct definition of the object guarantees that a true unique singleton instance exists.
This question regards how one can effectively create and persist event domain objects on certain system or user triggered events which themselves may or may not persist changes to the database.
Im creating a system where a user can tag some object, and when tagging occurs i should create a UserTagEvent which holds the object that was tagged, the tag that was applied or removed, and the user that tagged the object. (EDIT: This is not the actual TAG object, just a log of a tagging event)
The relationship of such a taggable object is one-to-many (a taggable object has many tags)
As far as i can see i have three alternatives.
Inline code in the controller/service which does the tagging (don't wanna do this as it mixes two different business processes.)
Use hibernate listeners pre-collection-update and post-collection-update to fetch the necessary information and create and persist a new UserTagEvent
Use AOP.
Do i have any other alternatives? Has anyone done something similar to this? What do you guys think i should do? Any help is appreciated.
It is not 100% clear if the UserTagEvent represents the actual tag or if it just acts as a log for a tag event.
Use hibernate listeners pre-collection-update and post-collection-update to fetch the necessary information and create and persist a new UserTagEvent
If the UserTagEvent is your tag the hibernate listeners would not make much sense because they would only get fired when you create a UserTagEvent and add it to the object by yourself and then you won nothing.
Inline code in the controller/service which does the tagging (don't wanna do this as it mixes two different business processes.)
I would start by creating a TagService that is responsible for tagging/tag-logging. You could use it either from a controller or by using it from aop but you should encapsule the functionality like: tagService.createTag(tag, object, user)
This could be handy especially when you later want to use a different technology to store the events like some nosql solution.
The following is what i learned when exploring my options:
1) Inline code in the controller/service which does the
tagging (don't wanna do this as it
mixes two different business
processes.)
Didnt give this alternative a try
2) Use hibernate listeners pre-collection-update and
post-collection-update to fetch the
necessary information and create and
persist a new UserTagEvent
This turned out to be very difficult, inefficient, and problematic for several reasons.
For example, you are working with a collection of items which may or may not be lazy initialized. In order to detect changes in the collection i had to listen for collection initialization event, get a cloned collection, store it to a field variable, then listen for a update collection event, get a cloned collection and compare with the collection previously stored.
In addition these events got fired for ALL hibernate events, not just for the domain objects i was interested in. So this was a "no go"...
3) Use AOP.
I was originally very optimistic about this solution, and after a few tries i soon came to realize that this wasn't as simple as i first thought. There were very few guides on the web describing Grails AND AOP, and those existed were rather old.
There was a lot more work involved than i originally thought. My overall impression is that grails seems to have a lot of bugs assosciated with AOP integration, and i also didn't like the fact that i had to add bean definitions to resources.groovy for each aspect that i created. I tried to make aspects be autoloaded through annotations (auto-proxy), but with no luck.
In addition i never got the pointcut to work outside the main project. As my tagging solution is defined as a grails plugin it seems that AOP can't be applied on classes of the plugin (even if it is a inplace plugin).
So this turned out to be a "no go" aswell
So drum roll please.
What i ended up with was using the observer pattern to fire off an event whenever a new tag was added or removed. This involved making changes to my tagger plugin where i could specify listeners through spring beans (whicn implemented a TagEventListener interface) and have the tagger plugin fire off events on the spring beans upon the addTag and removeTag method calls.
Overall im pretty happy with this solution, it involves one or two more method calls then what would be necessary if i had just inlined as described in option 1. But this way I have cleaner code, and i don't mix business processes. So i think the extra 1ns overhead is worth it.
AFAIK JSR-303 is the standard bean validation system.
I don't know whether it could do validations like this (I guess no):
if an object has a deleted flag set, you cannot modify the object
you cannot change the start date property, after the date is passed
you cannot decrease some integer properties in the bean
So how can I handle validations, which depend on the previous state of an object?
I would like to solve problems like that in hibernate3.5 - spring3 - JPA2 environment.
Thanks
My solution was to mess with hibernate, reload the object to see the old state (after evicting the new object). This time I need some smarter solution...
I don't think this can be done using JSR 303 validation (or any other validation framework I've used). Validation is usually stateless - you pass it an instance of an object, and your validation framework tests things to make sure the current values of your object are valid. There's no real knowledge of previous states of the object.
You can do this - just not with validation. You could use a constrained property, or you could make this work using the proxy pattern or AOP.
It sounds like the fields which you want to validate (with regards to previous state) are all metadata about the records as opposed to real data. All of these fields (idDeleted, createdDate, etc.) are better left out of your domain layer and therefor do not require validation. I would put the logic for determining & setting these values in you data-access layer so that the systems using your repository interfaces do not need to know or care about getting them right.
If my assumption about these fields being meta-data is not correct and you have user-entered data which validation depends on previous state, then I do not think that an extra lookup for the previous values is absurd and should not be out of the question. It makes sense in your case. Hibernate itself does a lookup under then hood to determine whether to INSERT or UPDATE when using it's save function.
Hope you find a reasonable solution.
how can I handle validations, which depend on the previous state of an object?
I'm not 100% sure it's doable but the only way I can think of would be to create an object graph made of the "new state" and the "old-state" (transient) and to validate the object graph as a whole using custom constraints. That's at least what I would try.
I would probably create a transient field that says previous version which points to a copy of the data that represents its previous state. This object is created on construction but since it is marked as transient it is not serialized. Then do the validations against it.
Simplest implementation would be to add a method called makeACopy() which makes a copy of the object and put it into the field.
You can add complexity by implementing Clonable or creating a utility class that would do reflection, but that's up to you. I suggest makeACopy() and refactor later since it is easier to think about.
I don't know any ready-to-use solution either. As you suspect JSR-303 won't do the job, because it's validation is 'static'.
But...
An idea would be to use some AOP techniques to do that. So...
if an object has a deleted flag set, you cannot modify the object
This one I would implement as a proxy method registered around every setter. The proxy method would check the 'deleted' flag. If it was set to true, an exception would be thrown, otherwise the original method would be executed.
you cannot change the start date property, after the date is passed
This one is similar. This time you wouldn't access any other property in the intercepted setter, but the original (not changed yet) value of the field and setter argument.
you cannot decrease some integer properties in the bean
That one is the same as with the dates, the only difference is the date type (date vs integer).
One can argue if AOP is a good choice for this task, but still a solution. I am doubtful too.
One more concern is that I guess you would want to enforce these contraints on JPA entities. So using Spring AOP wouldn't be that easy, since the entities wouldn't be Spring managed.
A completely different approach is to put the validation checks into the setters of properties. The downside is that you would lose declarativeness.
Example:
public void setCounter(int newCounter) {
if (newCounter < this.counter) {
throw new IllegalOperationException("Cannot decrease the counter");
} else {
this.counter = newCounter;
}
}
You might want to look at OVal instead. We do this kind of validation all the time. Normally, it's done using the SimpleCheck where you get the object and the value and can do all kinds of cross-checking.
In my domain I have objects that are constantly being updated by a separate process, and I want a PropertySheetView to display the changing properties. The current implementation is set up such that the underlying domain model object is immutable, and thus when it changes, there is a new object published with a corresponding ID. At that point, my Node wrapping the object has subscribed, gets the updated object with a matching ID, and recreates the Sheet (via createSheet()) and calls setSheet with the updated information. This works fine at always showing the most recent version of the domain model object.
However, some of the properties are not read-only, but instead can be set. I would like to lock the sheet from being updated / overwritten, on either a row or sheet basis, while a property is being edited. In order to do this I need to listen for edit start and end calls so I can know when it's safe to update the sheet again.
This is crucial for my application; as it stands now you can't get through entering a new value before the sheet is refreshed and your edit goes away.
If it matters, I'm using a custom PropertyEditorSupport, but the default InplaceEditor.
I've done a lot of searching through the NetBeans source and I don't see any exposed API settings to listen for this stuff.
SheetCellEditor (org.openide.explorer.propertysheet) exposes an addCellEditorListener method, but A) I can't figure out how I would get a handle on the SheetCellEditor instance, and B) the methods exposed by SheetCellEditor are editingCanceled and editingStopped - there is no callback for editing started! Seems very silly. The SheetTable and BaseTable would expose this property too, as they extend JTable, but I cannot figure out how to get a handle to them either.
I notice that the CellEditor interface requires the method isCellEditable(), which supposedly returns true if the cell can be edited, and thus the editing begins. But again, this is implemented by the SheetCellEditor which is not a public class, and I don't know how to get a reference to it.
Thank you for your help.
The best solution I could come up with was as follows:
Create a custom property editor. Make that editor implement InplaceEditor. Return a StringInplaceEditor which is a textfield. Attach a focus listener to that textfield. When focus is in the text field, it is being edited. Otherwise it is not.