Bean Validation for Super class - java

Hi I have a question regarding Bean Validation (JSR-303). We can validate one bean against set of annotations provided in a bean. What if i have a Bean Car which extends Bean Vehicle, and if i pass Bean Car to the validator, how to make Bean Vehicle(i.e. Super Class) also get Validated ?
I am using this Bean Validation in Camel. Below is my Code
public void configure() throws Exception {
from("file:data/source?noop=true").process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
System.out.println("Process 1");
Car car = new Car();
//this property is of Super Class
//car.setVehicleId(1);
car.setName("Swift");
car.setCompany("Maruti");
exchange.getIn().setBody(car);
}
}).to("bean-validator://v").process(new Processor() {
#Override
public void process(Exchange arg0) throws Exception {
System.out.println("Exchange is : "+arg0.getIn().getBody(Car.class));
}
});
}
My Car Bean is
public class Car extends Vehicle{
#NotNull
private String name;
#NotNull
private String company;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
My Vehicle Bean is
public class Vehicle {
#NotNull
private int vehicleId;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
}
Thank you. Help will be greatly appreciated.

I got this working. The problem is i have used primitive types in Vehicle [ private int vehicleId; ]
So i corrected it with [ private Integer vehicleId; ]. So after this my Vehicle bean is
public class Vehicle {
#NotNull
private Integer vehicleId;
public Integer getVehicleId() {
return vehicleId;
}
public void setVehicleId(Integer vehicleId) {
this.vehicleId = vehicleId;
}
}

Related

How to implement a Custom DataType in Hibernate?

We would like to type various properties in Java.
e.g. the e-mail address
But now I get the message all the time:
Could not set field value [test#test.de] value by reflection : [class customer.email] setter of customer.email;
Can not set dataType.EmailAddress field customer.email to java.lang.String
How should I proceed?
#Entity
public class customer {
#Id
#GeneratedValue
private Long id;
private String name;
private EmailAddress email;
}
public class EmailAddress {
public String value;
public EmailAddress(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
public boolean setValue(String s) {
this.value = s;
return true;
}
public String mailbox() ...
public String host() ...
public String tld() ...
}
Getter and Setter from HibernateDefaultType not called.
EDIT:
At the end. I want to store a String in the database with the email-Address. In Java I want the EmailAddress Object.
it is much easier. An AttributeConverter make it very easy.
https://thorben-janssen.com/jpa-attribute-converter/
Thank you very much
EDIT:
Here is the Code:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
#Converter(autoApply = true)
public class EmailAddressConverter implements AttributeConverter<EmailAddress, String> {
#Override
public String convertToDatabaseColumn(EmailAddress emailAddress) {
return emailAddress.value;
}
#Override
public EmailAddress convertToEntityAttribute(String s) {
return new EmailAddress(s);
}
}
And in the Entity:
#Convert(converter = EmailAddressConverter.class)
private EmailAddress email;
Here is some example of making your own custom type.
public class EmailAddressDescriptor extends AbstractTypeDescriptor<String> {
protected EmailAddressDescriptor() {
super(String.class, new ImmutableMutabilityPlan<>());
}
#Override
public String toString(String value) {
return null;
}
#Override
public String fromString(String string) {
return null;
}
#Override
public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
return null;
}
#Override
public <X> String wrap(X value, WrapperOptions options) {
return null;
}
#Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
return null;
}
}
Then you would make the Email address class with all your methods
public class EmailAddress extends AbstractSingleColumnStandardBasicType<String> {
private String value;
public EmailAddress() {
super(new VarcharTypeDescriptor(), new EmailAddressDescriptor());
}
#Override
public String getName() {
return "EmailAddress";
}
#Override
public Object resolve(Object value, SharedSessionContractImplementor session, Object owner, Boolean overridingEager) throws HibernateException {
return null;
}
}
public String mailbox() ...
public String host() ...
public String tld() ...
How you would use it with your entity will be something like this
#Entity
#TypeDef(name = "emailAddress", typeClass = EmailAddress.class)
public class customer {
#Id
#GeneratedValue
private Long id;
private String name;
#Type (type = "emailAddress")
private EmailAddress emailAddress;
}
Hope this helps

Hazelcast Deserialization: Parent class attributes values are null after deserializatioin

I have two class Parent Class and Child classes as below:
#MappedSuperclass
public class ParentEntity implements DataSerializable {
private String createdBy;
private Date createdAt;
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Long getCreatedAt() {
return createdAt.getTime();
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(createdBy);
out.writeLong(this.getCreatedAt());
}
#Override
public void readData(ObjectDataInput in) throws IOException {
createdBy = in.readUTF();
createdAt = new Date(in.readLong());
}
}
Child class is as below:-
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
id = in.readUTF();
name = in.readUTF();
}
}
I fetch these value from database and put into hazelcast cache iMap.
While getting values from cache I am getting id and name value correct, but createdAt and createdBy (Parent Class attributes ) values are null.
How can it is possible to serialize parent class also with child class.
You need to call super-class serialization methods in the child class methods. For instance;
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id; }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
super.writeData(out);
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
super.readData(in);
id = in.readUTF();
name = in.readUTF();
}}

when the Get request is other than Id getting this exception :Failed to convert value of type java.lang.String to required type java.lang.Long

In my SpringBoot code When i make use of Get request for user/{id} is working fine but when use of the request user/modelname.
I'm getting the exception:
Failed to convert value of type 'java.lang.String' to required type
'java.lang.Long';
carController.java
#GetMapping("/user/{id}")
public Car getUser(#PathVariable Long id) {
return carRepository.findOne(id);
}
#GetMapping("/user/modelname")
public List<Car> searchUserByModel(#RequestBody String modelname) {
return carRepository.findByModelname(modelname);
}
carRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
public interface CarRepository extends JpaRepository<Car, Long>{
public List<Car> findByModelname(String modelname);
}
car.java
#Entity
public class Car {
#Id
#GeneratedValue
private Long id;
private String modelname;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getModelname() {
return modelname;
}
public void setModelname(String modelname) {
this.modelname = modelname;
}
public Car(Long id,String modelname) {
this.id=id;
this.modelname = modelname;
}
#Override
public String toString() {
return "Car [id=" + id + ", modelname=" + modelname +"]";
}
public Car() {
}
}
Your request is not reaching to #GetMapping("/user/modelname"). it is always going to #GetMapping("/user/{id}") only because it satisfied the condition.
Try changing the url to something else like this #GetMapping("/users/modelname") and check ,it will hit definitely.

Json Object conversion to java object using jackson

I have following json data
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
I want to set this data to my pojo object
public class TestObject {
private Long id;
private String name;
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
}
Here i am able to set id and name in my test object but for object map i am not able to set data.
So i have made on more class for ObjectMap which contains programmeTitle & workingTitle this works fine but i can't set this fields directly to my pojo object
is this possible to set?
I am using Jackson Object Mapper to convert json data.
It is working fine if i create another java object inside my pojo like:
public class TestObject {
private Long id;
private String name;
#JsonProperty("objectMap")
private ObjectMap objectMap;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ObjectMap getObjectMap() {
return objectMap;
}
public void setObjectMap(ObjectMap objectMap) {
this.objectMap = objectMap;
}
}
public class ObjectMap {
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
public String getProgrammeTitle() {
return programmeTitle;
}
public void setProgrammeTitle(String programmeTitle) {
this.programmeTitle = programmeTitle;
}
public String getWorkingTitle() {
return workingTitle;
}
public void setWorkingTitle(String workingTitle) {
this.workingTitle = workingTitle;
}
}
If your JSON is like this
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
then you may write your object mapper class like this..
public class Program{
public static class ObjectMap{
private String programme_title, working_title;
public String getprogramme_title() { return programme_title; }
public String getworking_title() { return working_title; }
public void setprogramme_title(String s) { programme_title= s; }
public void setworking_title(String s) { working_title= s; }
}
private ObjectMap objMap;
private String name;
public ObjectMap getobjectMap () { return objMap; }
public void setObjectMap (ObjectMap n) { objMap= n; }
private Long id;
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
please refer this check it
You can write your own deserializer for this class:
class EntityJsonDeserializer extends JsonDeserializer<Entity> {
#Override
public Entity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Root root = jp.readValueAs(Root.class);
Entity entity = new Entity();
entity.setId(root.id);
entity.setName(root.name);
if (root.objectMap != null) {
entity.setProgrammeTitle(root.objectMap.programmeTitle);
entity.setWorkingTitle(root.objectMap.workingTitle);
}
return entity;
}
private static class Root {
public Long id;
public String name;
public Title objectMap;
}
private static class Title {
#JsonProperty("programme-title")
public String programmeTitle;
#JsonProperty("working-title")
public String workingTitle;
}
}
Your entity:
#JsonDeserialize(using = EntityJsonDeserializer.class)
class Entity {
private Long id;
private String name;
private String programmeTitle;
private String workingTitle;
//getters, setters, toString
}
And usage example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper.readValue(jsonString, Entity.class);
System.out.println(entity);
}
}
Above program prints:
Entity [id=10606, name=ProgrammerTitle, programmeTitle=TestProgramme, workingTitle=TestProgramme]

JAXB #XmlIDREF in XmlAdapter for immutable objects

I'm using XmlAdapter for immutable objects as proposed in this blog post: http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html. This works fine, but not with references to other immutable objects in my adapters. Is there any way to handle this with JAXB?
Below there is an example which does not work if the person's xml tag comes after the company's xml tag which references the person.
Immutable objects:
#XmlJavaTypeAdapter(PersonAdapter.class)
public class Person {
private final String id;
private final String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
#XmlJavaTypeAdapter(CompanyAdapter.class)
public class Company {
private final String name;
private final Person principal;
public Company(String name, Person principal) {
this.name = name;
this.principal = principal;
}
public String getName() {
return name;
}
public Person getPrincipal() {
return principal;
}
}
PersonAdapter:
public class PersonAdapter extends XmlAdapter<AdaptedPerson, Person> {
public static class AdaptedPerson {
#XmlID
#XmlAttribute
String id;
#XmlAttribute
String name;
}
#Override
public AdaptedPerson marshal(Person v) throws Exception {
AdaptedPerson a = new AdaptedPerson();
a.id = v.getId();
a.name = v.getName();
return a;
}
#Override
public Person unmarshal(AdaptedPerson v) throws Exception {
return new Person(v.id, v.name);
}
}
CompanyAdapter:
public class CompanyAdapter extends XmlAdapter<AdaptedCompany, Company> {
public static class AdaptedCompany {
#XmlAttribute
String name;
#XmlIDREF
#XmlAttribute
Person principal;
}
#Override
public AdaptedCompany marshal(Company v) throws Exception {
AdaptedCompany a = new AdaptedCompany();
a.name = v.getName();
a.principal = v.getPrincipal();
return a;
}
#Override
public Company unmarshal(AdaptedCompany v) throws Exception {
return new Company(v.name, v.principal);
}
}

Categories