Know when value of any variable defined inside the class is changed - java

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.

Related

Is using one class to store data safe?

So I was searching about storing data in one class, and found this. However, that's not what I'm looking for. What I wanted to know about this was whether it's bad practice, can cause performance issues in an application, or if there's another way to do it, etc... (and I'm not doing this on an Android).
Let's say I have a class that stores a HashMap<Enum, Object> and is initialized when I create the class in main.
public Main() {
// Creates the HashMap, initialized in the constructor 'MemoryContainer'
MemoryContainer m = new MemoryContainer();
m.getTestHash().put(SomeEnum.TEST, "Test"); // Using created HashMap
}
Other than casting the value every time I use it, would this cause major issues? If so, is there an alternative?
There's nothing wrong with storing static values in a class, however this is not a good practice.
To store the constants you should create an interface as every field in an interface is already a constant (public static final).
A better approach will be to store these values in properties files, and load them as needed.
A properties file can be stored externally and a person who isn't aware of your source code would be able to modify this properties file if needed. For example you can store database connection details in properties files and if server support admin determines that database instance is down, he/she can edit the properties file to point the application to a new one.
Finally for most flexibility you shouldn't store the configuration inside application at all. It can be stored in a database like MySql or in a fast data structure storage like Redis. This will allow multiple instances of your application to share the configuration data and it will also allow you to modify configuration on the fly by modifying them in the database.
Sometimes a Git repository is also used to store this kind of data (like in case of microservices). Git repository in addition to being shared among all the instances, also maintains the history of modifications.
I would not look too much at performance issues (of course, I do not know what else your application does or wants to do and how it achieves it).
What you should look at first is Mutability - in your example, nothing would stop me from changing the configuration at Runtime by calling
m.getTestHash().put(SomeEnum.TEST, "NotATestAnymore") - this would immediately change the behaviour for every other use of that specific setting.
I am also not sure why you would not just use a configuration class that would directly provide (typed) getters and, if you know all configuration settings at the launch of the app, one constructor containing all the settings.
Do you plan to read the configuration from an outside source (e.g. file)?
NO,
It won't cause major issues.
Also, it is a good practice to keep those variables (HashMap in your case) in a different class away from your main class (which contains your app logic).

Test the behaviour of concurrent code

I have an object which after receiving some message changes state asynchronously (an internal thread changes the state). After the state changed I want to test some behavior.
So basically I need to do something like:
Create object
Send message to object
Wait for state to change
Test behavior
However, the state is private and not exposed.
Is there an elegant solution to this that does not require exposing the state?
And if not - is it reasonable to require changing the main code just to make it more testable?
if the state is private, it is only accessible within its own class (https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html) meaning that you will not be able to get the state from your newly created object without modifying the class.
Now, whether it is reasonable to modify the class in order to do some testing is up to several factors:
How many people working on that code?
How many people already using a previous version of that code?
Integrity issues that you would face if you change the state variable to public and add a getter method.
etc.
So of course I can't tell you if it is reasonable or not without knowing in detail the organization of your software.
I hope this short answer helps you at least to clarify the problem.
You can access the relevant private fields with Reflection assuming you have the permissions to do so.
Foo bar = new Foo();
bar.setValue(true);
Field field = Foo.class.getDeclaredField("value");
field.setAccessible(true);
Object value = field.get(bar);
That will get the value stored in a private variable in the class.
This is pretty ugly and you probably shouldn't do it but if you really need to avoid altering the class you're testing with then it should do the trick.

"Dynamic" java validation framework?

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.

Reading the same ResultSet from multiple threads

In the database, I have a definition table that is read from the application once upon starting. This definition table rarely changes, so it makes sense to read it once and restart the application every time it changes.
However, after the table is read (put into a ResultSet), it will be read by multiple handlers running in their own threads.
How do you suggest to accomplish this?
My idea was to populate a CachedRowSet, and then create a copy of this set (through the createCopy() method) for each handler every time a new request comes.
Do you think this is wise? Does this offer a good performance?
Thanks.
It may be better for you to use the singleton pattern. This would allow you to create a single class that all of your threads could access to get the object that they needed. This could also allow you to not have to shut down your application whenever changes are made. One way to accomplish this is to have a class where you have get and set methods for the information you need. And another class that will give out references of that object.
The class that gives out references could have a private constructor, and a getInstance method that will return a reference to itself to ensure that only one exists. This would also give you some other options regarding what you can do when things change.
Ok, if you control access to the resultSet, and you don't care to update the result set until you restart the application, then i would suggest wrapping the CachedRowSet in a custom class. One possible way to do this is to have a wrapper class that is a singleTon and provide it with getter methods so that other threads or classes for that matter can access it. That way you remove the need to make a copy and remove the dependency on CachedRowSet implementation. Creating a copy would cause unnessary overhead. Imagine, in the way you described above, if you had 1000 threads accessing your result set, you would call createCopy() 1000 times thus creating a 1000 copies of the same resultSet.
I think it is a pattern to read the configuration table into a static data structure (ConcurrentHashMap) and then let the threads to look it up.
You can ensure that there is no write race at startup by populating the reference map from a Servlet.init() - it is guaranteed to execute once per servlet.

In Java, how can I construct a "proxy wrapper" around an object which invokes a method upon changing a property?

I'm looking for something similar to the Proxy pattern or the Dynamic Proxy Classes, only that I don't want to intercept method calls before they are invoked on the real object, but rather I'd like to intercept properties that are being changed. I'd like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 would be fine.
Here's what I want to achieve in general:
I have a thread running with an object that manages a list of values (numbers, strings, objects) which were handed over by other threads in the program, so the class can take care of creating regular persistent snapshots on disk for the purpose of checkpointing the application. This persistor object manages a "dirty" flag that signifies whether the list of values has changed since the last checkpoint and needs to lock the list while it's busy writing it to disk.
The persistor and the other components identify a particular item via a common name, so that when recovering from a crash, the other components can first check if the persistor has their latest copy saved and continue working where they left off.
During normal operation, in order to work with the objects they handed over to the persistor, I want them to receive a reference to a proxy object that looks as if it were the original one, but whenever they change some value on it, the persistor notices and acts accordingly, for example by marking the item or the list as dirty before actually setting the real value.
Edit: Alternatively, are there generic setters (like in PHP 5) in Java, that is, a method that gets called if a property doesn't exist? Or is there a type of object that I can add properties to at runtime?
If with "properties" you mean JavaBean properties, i.e. represented bay a getter and/or a setter method, then you can use a dynamic proxy to intercept the set method.
If you mean instance variables, then no can do - not on the Java level. Perhaps something could be done by manipulations on the byte code level though.
Actually, the easiest way to do it is probably by using AspectJ and defining a set() pointcut (which will intercept the field access on the byte code level).
The design pattern you are looking for is: Differential Execution. I do believe.
How does differential execution work?
Is a question I answered that deals with this.
However, may I suggest that you use a callback instead? You will have to read about this, but the general idea is that you can implement interfaces (often called listeners) that active upon "something interesting" happening. Such as having a data structure be changed.
Obligitory links:
Wiki Differential execution
Wiki Callback
Alright, here is the answer as I see it. Differential Execution is O(N) time. This is really reasonable, but if that doesn't work for ya Callbacks will. Callbacks basically work by passing a method by parameter to your class that is changing the array. This method will take the value changed and the location of the item, pass it back by parameter to the "storage class" and change the value approipriately. So, yes, you have to back each change with a method call.
I realize now this is not what you want. What it appears that you want is a way that you can supply some kind of listener on each variable in an array that would be called when that item is changed. The listener would then change the corresponding array in your "backup" to refect this change.
Natively I can't think of a way to do this. You can, of course, create your own listeners and events, using an interface. This is basically the same idea as the callbacks, though nicer to look at.
Then there is reflection... Java has reflection, and I am positive you can write something using it to do this. However, reflection is notoriously slow. Not to mention a pain to code (in my opinion).
Hope that helps...
I don't want to intercept method calls before they are invoked on the real object, but
rather I'd like to intercept properties that are being changed
So in fact, the objects you want to monitor are no convenient beans but a resurgence of C structs. The only way that comes to my mind to do that is with the Field Access call in JVMTI.
I wanted to do the same thing myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, wrap my proxy class around original class, and delegate all method calls on proxy to the original, except setters which would also fire the PropertyChangeEvent.
Anyway I posted the full explanation and the code on my blog here:
http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html

Categories

Resources