A field has two validation annotations
#NotEmpty
#Length(min=3,max=100)
String firstName;
Observation
If that field is left empty, then the resulting violations vary in order:
sometimes the #NotEmpty is violated first
other times the #Length is violated first
Questions
How does Hibernate specify the order in which validations (annotations) are processed?
Can this validation order be customized?
Thanks in advance.
Use JSR-303 validation groups.
If no groups are specified a constraint is part of the Default Bean Validation group (see: javax.validation.groups.Default).
Create an interface to be your "Extended" (or whatever you want to call it) group:
public interface Extended{}
Now create an interface that will have the javax.validation.GroupSequence annotation.
#GroupSequence({Default.class, Extended.class})
public interface MySequence {}
Set the validation groups on your constraints
#NotEmpty // If no group is specified it is part of the default group
#Length(min=3,max=100, groups = Extended.class)
String firstName;
Pass MySequence to your validator call.
validator.validate(object, MySequence.class);
As specified by your #GroupSequence the default constraints will be validated first and if no contraint violations are encountered it will move on to the extended group.
Just to add to the above answer, the group sequence could also be done at the Class level where validations have been defined.
For example:
Provided we have two interfaces
public interface FirstOrder{}
public interface SecondOrder{}
We could define them as a group sequence as below
#GroupSequence({MyTestClass.class,FirstOrder.class,SecondOrder.class})
public class MyTestClass{
#NotBlank(groups = FirstOrder.class)
#Length(min=3, max=100, groups = SecondOrder.class)
private String name;
}
Advantage of doing the group sequence this way is -
You do not need an extra interface to define the group sequence and as a result you do not need to pass that to the validator for your unit/IT tests.
Related
I have a scenario where I have the user table and the address table. The address table is a value objects in domain driven design in my understanding. How do I store value objects in mysql database? this sounds a bit confusing but I couldn't understand this idea value objects are immutable but how to store them?
Below are classes of my two entity
user.java
#Getter #Setter #NoArgsConstructor
#Entity // This tells Hibernate to make a table out of this class
#Table(name="user")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#JsonProperty("userid")
#Column(name="userid")
private Long user_id;
#JsonProperty("user_nome")
private String nome;
#JsonProperty("user_email")
#Column(unique = true, nullable = false)
private String email;
#JsonProperty("user_cpf")
private String cpf;
#JsonProperty("user_telefone")
private String telefone;
#JsonProperty("user_celular")
private String celular;
#JsonProperty("user_senha")
private String senha;
#Column(name="createdAt", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
#Temporal(TemporalType.TIMESTAMP)
#JsonProperty("user_createdAt")
private Date createdAt;
#Column(name="updateAt", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
#Temporal(TemporalType.TIMESTAMP)
#JsonProperty("user_updateAt")
private Date updateAt;
/*Person p1 = new Person("Tom", "Smith");
p1.setId(1L);
p1.setStartDate(new Date(System.currentTimeMillis())); */
}
class Address:
#Getter #Setter #NoArgsConstructor
#Entity // This tells Hibernate to make a table out of this class
#Table(name="address")
public class Address {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#JsonProperty("address_id")
private Long address_id;
#JsonProperty("address_endereco")
private String endereco;
#JsonProperty("address_bairro")
private String bairro;
#JsonProperty("address_numero")
private String numero;
#JsonProperty("address_complemento")
private String complemento;
#JsonProperty("address_cidade")
private String cidade;
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "userid")
private User userid;
}
Basically however you want: you could enforce immutability in the database, but you don't have to. Immutability can be enforced in the database by creating an unique constraint on a combination of values of an address, zipcode + house number for example.
As a database administrator I personally don't like developers enforcing immutability in the database because I see implementing/enforcing business logic in the database as a category error. What is an immutable value within the domain, to me is just data that needs to be consistently stored. Database rules are meant to ensure data consistency and the added complexity of implementing immutability in the database can interfere with that. Lets do a thought experiment:
You ensure that an address value is unique in the database with a constraint that covers all properties and store your data. Some time later a customer places an order that happens to have the same address, but he lives on the North Pole. The order is saved but the address isn't because my server throws an error because the address violates the constraint because it already exsists in the US, but that's not saved/part of the constraint. Now I have a problem because that orphaned order violates the data model, you complain to me because my server threw an error and now it's up to me to figure out what's wrong with your design decision to apply the abstract concept of immutability outside your domain, and have to update the data definition in a production environment in order to fix it.
So I think it's best you acknowledge that by storing data it leaves your domain and that is a risk your design should take into account. What I'd advice (or silently implement haha) would be the addition of an ID within the table and a record versions of the same 'immutable value' for tracability, consistency and agility to react to unforseen circumstances. Just like with user and transaction entities ;)
I want to display a list of users in an XHTML page. I'm sending a request from my managedBean to the Business through an EJB (3.0) then another request to the DAO still through an EJB (3.0). I'm using JPA 2 and a MySQL database with an entity manager.
I'm sending the following request to my database
#Remote(IDaoUser.class)
#Stateless
Public class DaoUser implements IDaoUser
#PersitenceContext(unitName = "persistence_unit")
Private EntityManager em;
#Override
Public List<User> getAll() {
Query query = em.createQuery("SELECT u FROM User u");
List<User> users = query.getResultList();
return users;
}
At that point everything's fine and I get all my users in my list with all attributes especially id (primary key). My user class has one attribute (birthdate) and inherits from a super class Parent (name, forename, mail, phone...) which inherits again from another class called Who which has just one attribute called id (the primary key).
Then I return my List (users) to the business through an EJB and once in the business I realise all the id attributes are 0. I kept all the others attributes (name, forename...) except ids and I can't figure out why I'm losing these values.
There are well stored in my List in the DAO but all changed to 0 once in the business.
Here is my business class which is very simple
#Remote(IBusinessUser.class)
#Stateless
Public class BusinessUser implements IBusinessUser
#EJB
private IDaoUser proxy;
#Override
Public List<User> getAll() {
List<User> users = proxy.getAll();
return users;
}
Given the description of the problem, I would ask some questions
Are the parent classes entities themselves, i.e. are they annotated with #Entity.
You need to ensure that #Id is on your primary key. Do you have the #Id annotation on the primary key.
Experience has taught me to always have the #Id attribute in class or at least in a parent class tagged with the #MappedSuperclass. And some people still have problems with retrieving their id fields from the mapped super class.
So see the JEE documentation for using the MappedSuperclass annotation. This may require changing your object inheritance model but that shouldn't be a problem given your requirement.
Thanks for your help. Actually both parent classes are themselves entities. My super class "Who" is the only one having an id attribute (primary key) with the annotation #Id. I can't tag my super class with the #MappedSuperclass since it is associated to another class.
I'm quite new to JPA and using Java as backend for REST services, and I'd like to store a JSON into the database, and wanted to check what is the best way to do so. Please let me know in case I'm taking the "long path".
(I'm using Spring)
My data:
{
frequency: "Week"
isGoalOrMore: "true"
name: "Develop"
targetValue: "5"
type: "Average"
}
Habit.java
#Entity
#Table(name = "habits")
public class Habit {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "id_habit_type")
private HabitType type;
private boolean isGoalOrMore; //basically means, achieve goal or do more
private double targetValue;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "id_frequency")
private Frequency frequency;
//getters and setters
}
HabitType.java
#Entity
#Table(name = "habits_type")
public class HabitType {
#Id
private Long id;
private String description;
}
DB Model (mysql)
habits
--id
--name
--id_frequency
--id_habit_type
habits_type
--id
--description
Problem
When I try to save this data I receive an error as below:
com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.tiperapp.model.HabitType] from String value ('Average'); no single-String constructor/factory method
How can I solve it?
By reading some topics, one option would be to write a JSON deserializer. Other cases they solved it by fixing their JPA.
I'd like to know which would be recommend.. can you guys please help me how to deserialize this, the best way ?
The best solution, IMHO, is to think of the data that you send and receive to/from the browser (which I'll call the DTOs), and the data that you store in the database, as two distinct things.
Sure, they often look the same. But they're different. You can't have exactly the same model for both. For example:
the entities constitute a huge graph, often containing bidirectional associations, and which has no limit, since everything can be loaded lazily. For example, an order line has an order, which has a buyer, which has an address, which has a city, which has a country, which has... You can't reasonably serialize all this graph when the browser asks for an order line, otherwise you'll serialize half of the database to JSON.
the JSON sometimes has a different representation of the same thing than the database. For example, you store all the habit types in the database as a row with an ID and a description, but it seems the JSON only really cares about the description. The ID seems to be a way to avoid duplicating the same description everywhere.
many attributes of the entities can not be seen (for security reasons) by the end user, or are only relevant for some use cases, etc.
So I would thus use different classes for both. When you receive a HabitDTO as JSON, you deserialize it with Jackson to a HabitDTO instance, and then find the HabitType entity correspondint to the description in the DTO, and create/update the Habit entity instance based on the corresponding information in the HabitDTO.
To recap: the entities contain the complete business model of your application, used to implement all the functional use cases. The DTOs contain serialized information and are used to transfer a small part of the information to/from the client, often for a specific use case. Having a clear distinction between the two allows much more flexibility: you can change the underlying persistence model without changing the interface of your services, or vice versa.
Your json is wrong.
type is not mapped to a string but to an object. You can do that by using this :
{
frequency: "Week"
isGoalOrMore: "true"
name: "Develop"
targetValue: "5"
type: {
description: "A DESCRIPTION"
id: "Average"
}
}
Considering a Java class constructor that take two parameters but allows the second to be null.
public class Category {
String name;
#JsonIgnore Category parent;
Category(String name,Category parent){this.name = name;this.parent=parent;}
}
I skipped the serialization of parent with #JsonIgnore annotation because I don't need it. Now Jackson is not capable to deserialize it because it don't find the parent property in the resulting Jason.
Is there any another solution but to define a constructor taking only the name parameter?
It is ok to have named constructor parameters that are missing -- you will simply get null instead of value. So you could just have:
#JsonCreator
public Category(#JsonProperty("name") String name, #JsonProperty("whatever") Category parent) { ... }
and whatever is found is passed. No exception will be thrown; Jackson never requires a property to exist. It just complains about things it does not recognize (unless configured not to).
I'm looking for a good design pattern/strategy for how to using the Struts 2 framework for editing multiple objects of the same type on an HTML page. Struts is really good for editing a single object, like Address. If you provider accessor methods for address1, city, state, etc, struts calls those and the standard struts UI tags will populate the form fields accordingly.
How to do this when editing multiple of the same type of object on the same page. I have a web based contest, parting of the contest is a set of rating scale objects for each contest. Each rating scale has a value and a label. If I name the input fields value_0, value_1... and label_0, label_1... then I either have to code a bunch of accessor methods (UGLY) or use the raw parameters to get the values I need. It is difficult, but not impossible, to use the struts validation methods to send error messages back to the correct form field.
If I name all the fields "Value" and "label", struts is kind enough to call a method that sets a List of input values, but I have no way of sending validation errors back to the correct output field.
I need something that doesn't require a huge number of accessor methods, allows easy access to the inputs to validate, return validation messages to the correct form field.
The strategy here is to use a Map<Integer, Address>.
Example Bean Class
Let's assume the following example Address class.
public class Address {
private String line1;
private String line2;
private String city;
private String state;
private String zipCode;
// getters and setters here
}
Example Action
public class ExampleAction extends ActionSupport {
/**
* A map of ID -> Address.
*/
private Map<Integer, Address> addresses = Maps.newLinkedHashMap();
// ... action method(s) and validate here
public Map<Integer, Address> getAddresses() {
return addresses;
}
}
In your JSP layer, you can iterate over the map (each iteration is a Map.Entry) and output the fields (line1, line2, city, etc.) for each. The field names should be:
addresses[0].line1
addresses[0].line2
addresses[0].city
addresses[0].state
addresses[0].zipCode
...
addresses[5].line1
addresses[5].line2
addresses[5].city
addresses[5].state
addresses[5].zipCode
To perform validation, just iterate over the map and check each field appropriately. When editing addresses, you can use the primary key of the address from your database. For adding new addresses, you can just increment starting from zero. The index can be any number, so long as its unique within the map.
I typically map out everything I need to use in a form and group them into related classes, Person, Address, Misc for example. I will then create a wrapper class and use delegate accessor methods to provide a single interface to access the individual objects. Most often I work with JPA entites so these classes are already set up for me, I just need the wrapper and maybe some utility methods for CRUD functions. For example:
public class ContactWrapper implements Serializable{
private Person person;
private Address address;
private Misc misc;
// Getters / Setters for primary objects - person, address, misc
...
// Delegate accessors
public String getName(){
return person.getName();
}
public String setName(String name){
return person.setName(name);
}
...
}
Now you have one object to work with in your action class and jsp's which can be references however you choose.
In your action class:
public class ContactAction extends ActionSupport{
private ContactWrapper contact;
....
}
In your JSP:
<s:textfield name="contact.name" />
Struts handles all the object instantiation auto-magically, even in objects contained inside other objects.