My project have two main requirements
1) Different set of rules applied to same object at insertion and while updating it.
2) Different validation rules based on locale.
In ADDRESS object STATE field requires different validation rules
For USA: STATE cannot be NULL.
For everywhere else it can be NULL.
For first requirement i am already using GROUPS.
Is there a way to achieve second requirements.
I am using:
Hibernate Validator 4.0.1 GA
Hibernate 5.2.6
I would make the country (Locale based or not is up to you) part of the Address and use a custom class-level constraint to do the validation.
This question got answered on the Hibernate Validator forum. Best way to go is a class-level constraint or a Validator instance per Locale. I really wouldn't recommend the latter, but it's a possibility.
Related
I need to customise Liferay's default behaviour: currently, each organization must hava a unique name -- I need to override this behaviour to allow duplicate names. Also, currently there are lots of entities in current Organization_ table in database.
Is it possible to override default model and remove uniqueness constraint while preserving old entities? If yes, how would I approach this?
Of course, I could just add unique suffixes to new saved entities and remove them on display, but this approach seems wierd.
Is it possible to override default model and remove uniqueness
constraint while preserving old entities?
Yes, it surely is, as you can override everything in Liferay
If yes, how would I approach this?
Sarcastic Approach
identify all the places, where Liferay handles Organizations and might implicitly rely on their uniqueness.
hope that I indeed found all the places
evaluate if it's feasible to change all those places to not rely on the uniqueness of the name any more
hope that I found everything, and that my changes make sense
set aside a lot of money to pay for future maintenance of my changes, when I need to adopt the changes to future versions of Liferay.
to 10. determine that it's not worth it and move on to an alternative solution
Alternative Approach:
Determine where this new display is required
implement alternative name, e.g. through Expandos (Custom Fields)
change display where needed to show the Expando values instead of the organization's name.
Is it possible to turn off certain constraints / annotations per class at runtime? For instance if I wanted to turn of a #NotNull check on a firstName field, is that possible?
This would make testing to see whether a certain constraint is triggered correctly simpler, as I could turn off all the other constraints, and just check that one constraint.
Is it possible to turn off certain constraints / annotations per class
at runtime? For instance if I wanted to turn of a #NotNull check on a
firstName field, is that possible?
No it is not. Bean Validation does not define such a feature. There is an open issue in Hibernate Validator HV-98 which discusses the possibility of reloading metadata, but even there you would need to rebuild the validator factory.
You could override annotations via XML configuration and then recreate the Validator(Factory) instance using different configurations at the time, but that's probably not easy to mange.
This would make testing to see whether a certain constraint is
triggered correctly simpler, as I could turn off all the other
constraints, and just check that one constraint.
If it is about testing, you can use Validator.validateValue to just validate a given field. Other than that, if you validate the whole object graph and get a set of constraint violations back, you can just iterate over them and inspect the metadata. There is enough information in the metadata to verify that a specific constraints was executed and failed.
The hibernate validation annotation are usually used together with database constraints so it does not make sense to change the behavior at runtime. However if you want to do it you can implement your own validators (by overriding existing) and do whatever you want.
I've following problem, there's a regular spring model (let's call it "A") with some validations-related annotations. Next, there's a command object (regular POJO class that defines some field, one of them is object of type A). The command object implements Validator interface, to make binding and validation work in controller methods.
Question is, how to make use of annotations-configured validations inside the command object (given it implements Validator interface, hence it has supports() and validate() methods).
What I'm trying to achive is to have basic validations on model that is reused and mixed with some heavier business-logic validations in other parts of the system.
I have had the exact same problem. I wanted to use automatic annotation validation for "simple things" and then pass the complex validation logic to my custom spring Validator. But whenever I set the controller validator, all of hibernate's validation stopped working, as described at the end of this tutorial:
http://www.captaindebug.com/2011/07/applying-custom-spring-validator-to.html#.VQR0OI7F-gd
This technique should be used when you need to do ALL your
controller’s validation yourself, and you can’t or don’t want to make
use of the Hibernate’s reference implementation of a JSR 303
validator. From this, you’ll guess that you can’t mix your own custom
Spring validator with Hibernate’s JSR 303 validator. For example,
adding the built-in annotations to the Address command object will
have no effect:
You should forget about old style Spring Validator and delete "setInitBinder()" as described in this related question:
Spring MVC validator annotation + custom validation
You should then only rely on hibernate validation and JSR303.
To add a complex validation to your class (model), say you want to check two date fields - use a custom annotation constraint on class level as described in the link below.
https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-customconstraints.html#section-class-level-constraints
Hope this helps.
Best Regards,
Alexander
Once look at this may this help you
Using both JSR-303 and Traditional Bean Validation?. There i have given one example for custom validation for model using custom annotation.
What is the best practice for updating a model where only certain fields are meant to be updated?
Eg.
If I have a person model with:
Name
Birthdate
Address
And a form where I want to update only:
Address
The two options I can currently see are:
To have a custom form model that has only address - on postback call the DB to retrieve my object to fill in Name and Birthdate, then persist back to the DB.
Custom update SQL to only update the relevant fields.
I'd prefer to make use of the hibernate model if possible, so I'm using #1 currently.
Is there a better way?
How Hibernate constructs an SQL Update can be configured to update only the fields that changed, using an attribute called dynamic-update on the class mapping.
If hibernate leaves useful-looking functionality like this deactivated by default it's because there are trade-offs to be made. The linked documentation goes on to say:
The dynamic-update and dynamic-insert settings are not inherited by subclasses, so they can also be specified on the or elements. Although these settings can increase performance in some cases, they can actually decrease performance in others.
Best Practice is to skip performance optimization until you need it.
A project I work on (which uses Java, Spring, Hibernate) recently changed from Oracle to MySQL. There are a few cases where some of the properties in the code are reserved words in MySQL, such as "release".
There are a few solutions, 1) rename properties in the code and subsequent getter/setter methods, also update code that invokes those methods 2) annotate the property in the code with #Column(name="`release`"). This tells hibernate to quote the name when talking to the database.
I'd prefer to stay away from the first approach to reduce the chance of breaking more stuff. The second approach is "ok", except it becomes MySQL specific. In our dev. setup we use HSQL which doesn't like the backticks around those column names.
I looked at the org.hibernate.mapping.Column class and I see it has "getQuotedName" methods that I could potentially override if I could subclass Column and tell Hibernate to use my own Column class.
What's the best way to resolve this issue based on the preferred approach of a) not having to refactor the codebase (b/c of changing property names, getter/setter methods, etc) and b) wanting the app to still work in HSQL and MySQL.
It would be reasonable to have a property in properties file that could be toggled to switch on/off some Column naming fix. Which reminds me, I tried using a custom naming strategy and overriding the "columnName" method to surround the column name in backticks...this doesn't work, even on MySQL.
The back ticks solution sounds good. But if it does not work or you do not want to use an undocumented feature of an specific JPA providery: Why don't use column names that are not reserved in any(or the most common) databases at all.
You don't need to change the name of your java properties, you must only specify a column name for them.
Use backtips. It is your way of telling Hibernate that you want that identifier to be quoted properly. It's just a coincidence that backticks are also used as quoting character for MySQL. This backtick will be translated to whatever is the quoting character for your database. Regarding adding quotes as the default behavior, I'm not sure Hibernate have such option. Nothing in the documentation mentions a possible option, and I don't remember seeing anything like this in the test suite as well. But I don't think it's a good idea, as "reserved keywords" are exceptions, not the rule.