Can fields set by Hibernate be final? - java

My Eclipse does a number of code-cleaning actions automatically when I save a Java file, among them adding final to private fields where possible.
Will this conflict with Hibernate's ability to inject entity properties into private fields?
#Id
private final Long id = null; // Eclipse made this "final"
// but Hibernate needs to set the id
Should I turn this save action off?
Update: I have tested the application and also looked at it with a debugger, and Hibernate does indeed reset the "final" field, so things continue to work okay. But is this guaranteed to work? For example, are there no VM or compiler optimizations that rely on a field really being final. Those would probably break. On the other hand, being able to set private fields via reflection seems to be a supported scenario, so the same thinking probably applies to final as well?

Even if it work, don't do it.
A final field can be written exactly once, and parts of the java memory model based on this fact.
I found this blog http://www.polygenelubricants.com/2010/03/modifying-static-final-fields-through.html which showed that it is possible to set an final via reflection with an real Hack. (But please don't do this in any real application.)
And this answer to an related question: Is there any way to declare final fields for Hibernate-managed objects?
In your case the simplest soultion would be: make the field mutable, and provied only a getter but not a setter.

hmm interesting question. I think on persisted objects you probably don't want to autoset final, for exactly the reason you mention.
It will definitely be a problem if your class has some sort of functionality where you do something like
setProperty(int prop) {
this.prop = prop;
fireChanged(); // updates other fields that depend on this one
}
which I have seen in a professional context. Although maybe here the plugin is smart enough to not make it final.
If you want to make your objects immutable, you could have your persistent class return an immutable subclass of itself, where the fields are private....
So there are advantages and disadvantages to that plugin. I guess you can do it either way, as long as you have tests to verify the auto-generated finals don't get in the way. Personally I would not use that plugin though -- I would look at the IDE warning and pick and choose my finals...

Related

How to call methods that inject parameters in a unit test?

There is a pattern which is widely used in my current project:
private Collection<Converter<T>> converters = new HashSet<>();
#Inject
private void init(#Any Instance<Converter<T>> converters) {
for (Converter<T> converter : converters) {
this.converters.add(converter);
}
}
This way I can create as many converters as I want and they are automatically injected to my bean.
My problem is now with testing: the converters collection is used in my code, but Junit doesn't call the init(..) method and I need to call it to set the mocked converters.
I could make the method protected, but I don't feel OK with it because I would be changing the visibility scope of the method.
I could also call the method using reflection, but this also doesn't feel right.
This brings me to the conclusion that this code could be improved to be more testable.
Is there anyway I change this code so the testability is improved but the references are still automatically injected?
Just go ahead and make it 'public' or 'protected'.
You are not actually gaining any protection from someone changing the collection post-instantiation this way (you've just made it a little more awkward), so you don't lose anything by exposing that method (in fact I'd argue you make your class slightly better, because than you let people chose how they want to construct, rather than forcing a use of injection/reflection).
If you did want to fully prevent post-instantiation modification, than you're going to have to go to a 'final' variable anyway, with an unmodifiable collection type and change to constructor injection, but I don't get the impression that this is what you want to do.
Thing is: if you can't "trust" the people who can write code within your "package" ... I guess having "private" on a method doesn't really help you anyway. Because if people want to mess up, and they can write code in your package, they will find ways to mess up anyway.
Meaning: if you drop the "private" on your method, yes it becomes package-visible. But you can place a javadoc on it that says: "Don't call directly; used for unit test/auto-wiring only" or something like that.

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.

How to stop writing Java property setters for BlazeDS & JPA that I don't want?

BlazeDS will not serialize a property unless it has both a getter and a setter. However, many of my Java properties are read-only. Therefore I am now having to add setters to support the Unmarshalling process. If any of the users of these domain objects start calling these setters themselves it'll break the value-object semantics of these things and likely cause all sorts of system problems.
I've had to do this a lot on the past to support certain aspects of JPA and never liked it. This was because we put our JPA annotations on the properties rather than the private fields (to avoid another problem).
Other than use Javadoc to warn myself and others, what's a programmer to do?
Edit: I should add that these extra setters are NOT part of the public interface these objects implement....but they are still there nonetheless.
You could try using the #Access annotation. This is used to override the access type being used for the class on a column-by-column basis. It also lets you mess with stuff when it goes to the database, like this:
private String firstName;
#Access(AccessType.PROPERTY)
#Column(name="FIRST_NAME")
protected String getFirstNameForDatabase() {
return "Mr. " + this.firstName;
}
This example not only overrides the 'FIELD' access being used for the class, but it also causes the database to commit with "Mr. " prefixed on the value each time. This may also allow you to declare 'dummy' getters/setters that satisfy your other requirements without screwing up the JPA commits and retrieves. Try it out and see if this can be used to craft a solution for your issue.
You have several options: use your own serialization mechanism or use BlazeDS version 4. I wrote a small article related to that, maybe it can help you. The link is http://cornelcreanga.com/2009/09/blazeds-amf-and-read-only-properties/.

java - how to persist variable in JVM

I have an odd situation where i want to be able to be able to persist a variable in memory.. like a global variable I can pin in the JVM.
Is this possible? I remember doing something similar in college, but can't find it by googling. I have a logic problem that has some artificial constraints that make this the best possible solution.
EDIT 1:
I will need to update the value of the variable.
EDIT 2 :
I appreciate the responses guys. I'm a .net programmer and hadn't used java since college. Thanks again.
Yes, using a static field:
public class GlobalVariableHolder {
public static int globalVariable;
}
Note, however, that this is considered a bad practice and can lead to unexpected results that are hard to debug. The way to not use a global variable is to pass it around as an argument or methods where you need it.
If you are still sure you need this, in order to guard yourself as much as possible, use synchronization. Even better, if the variable is going to be primitive (int, long, etc), you can use AtomicInteger's getAndAdd() or addAndGet() method.
Usually you will end up storing these things in some kind of a global class--a class that is accessible from anywhere and has a controlled number of instances.
Singletons are commonly used for this. If you look up the pattern for a singleton and store your variable in that singleton (add a setter and a getter) you are on your way.
Doing this (as opposed to a public static variable) will give you some level of access control and traceability--for instance you can put debug statements in the getter if you find you are getting unpredictable results.
In the long run setters and getters and singletons are all bad code smells but no where near as bad as a settable public variable.
Later you may want to move the code that manipulates that variable into the singleton object and possibly convert the singleton to something you can fetch via IOC, but having a singleton is a much better place to start than with a public static.
Do you mean something that will exist across multiple invocations of java.exe, or do you mean a single variable that will be the same location in memory regardless of which thread within java.exe access it? Or do you mean a variable that can only be accessed if you're using JRockit? Or maybe just the JVM on your dev machine, but not on another system?
In the first case, you'd need another way to store it, like a config file.
In the second case, like Bozho says, use the static keyword.
In the third case, you'd probably need to use the System class and determine the JVM manufacturer (Assuming that's available from System - I'm not sure off the top of my head, and you'll learn more by looking up the API yourself).
In the fourth case, you're pretty much back to a config file.
Its not going to win any awards but this should work:
package mypackage;
public class MyGlobal {
public static String MY_GLOBAL_VAR = "my variable";
}
Any class within that JVM instance would be able to access MyGlobal.MY_GLOBAL_VAR.
Updated to allow update.

"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.

Categories

Resources