Getting value of attribute specified in JPA annotation - java

Assuming that I have some entity with a field annotated as follows:
#Column(name="title", length=255)
private String title;
how could I get the value of the 'length' attribute with Java?

Hibernate Validator (the reference implementation of the Bean Validation specification) can be used to do this type of validation without implementing your own annotation-based validator. Integration with JPA allows to execute the validation during the persist or update of an entity. It's an Hibernate project, but it can be used with other JPA providers like EclipseLink.

Using reflection try something like this.
Class<?> cls = Class.forName(name);
Annotation ety = cls.getAnnotation(Column.class);
int value1 = a.length();
Although this can be done with the code above. I don't recommend use reflections to do this at all.
Try to use JSR-303 and javax.validation.constraints, there are pretty easy to use.

Related

Java validation of object with annotation directly

The conventional way of java validation is to define a class with properties and annotated with one or many validation constraint annotations such as #NotNull or #Future.
Is it possible to validate an object directly with validator constraint annotation without specifying a class. For example:
String a = "";
validator.validate(a, javax.validation.constraints.NotNull.class);
That's clearly not a use case for which Hibernate Validator has been designed.
What you would have to do is to create a ConstraintValidator from the constraint and the type of the object and then use the isValid() method. The entry point would be ConstraintValidatorManager.
It's an internal class so it's subject to change without warning, even in a micro version so I wouldn't recommend using it.

#Transient not working in hibernate

I am using hibernate 4.1.9.
My code is
#Transient
private String ldapIdTemp;
package is
import javax.persistence.Transient;
Still in hibernate query, it is not working and putting the attribute in the query.
part of query snippet (assetasset0_.ldapIdTemp as ldapIdTemp16_0_, )
I am not sure what I am doing wrong.
Can you try creating setter and getter for the field and annotate the get method with #Transient, as follows:
private String ldapIdTemp;
#Transient
public String getLdapIdTemp() {
return ldapIdTemp;
}
public void setLdapIdTemp(String ldapIdTemp) {
this.ldapIdTemp = ldapIdTemp;
}
Much depends on how you "integrated" this field in your Entity or class hierarchy. Moreover, field vs. property-access could cause an issue for your setting. See this post for a detailed explanation.
In your case, I could imagine that you either:
mixed field and property-access in your entity inheritance strategy
use XML-based configuration for Hibernate in your application.
In both cases the JPA 2.0/2.1 specification clearly states in Section 2.3.1:
It is an error if a default access type cannot be determined and an access type is not explicitly specified
by means of annotations or the XML descriptor. The behavior of applications that mix the placement of
annotations on fields and properties within an entity hierarchy without explicitly specifying the
Access annotation is undefined.
Please check that your persistent Entity classes have either field OR property-based annotations.
Check the #Transient annotation fully qualified name.
It can be from either,
org.springframework.data.annotation.Transient or javax.persistence.Transient.
Try to use javax.persistence.Transient.

org.apache.struts2.json.annotations.JSON doesn't show right format

My web application uses struts2-json-plugin-2.2.1
I have an action that exposes an object loaded from DB (through hibernate).
This object contain a java.util.Date field that is so annotated:
#JSON(format = "dd-MM-yyyy")
#Column(name = "DATA_CREAZIONE", nullable = false)
public Date getDataCreazione() {
return this.dataCreazione;
}
Instead of getting:
"dataCreazione":"15-02-2013"
I get this:
"dataCreazione":"2013-02-15T16:51:06"
In debug I notice that the org.apache.struts2.json.JSONWriter class doesn't find any annotation over the getDataCreazione method and that the proxy class is of the "$$_javassist" type rather than "$$EnhancerByCGLIB$$" as other cases...
In the same application I have a lot of this situations and the annotation works fine.
I don't understand what is the problem (or the difference) with other classes.
Do you have any suggestions?
You didn't specify name of the annotation attribute. By default annotations with empty names are not deserialized. For further references take a look at the Apache docs.
btw I confirm the origin of my problem. As I said before it resides in the proxy class that are used. In my case - if I load the object (through hibernate) then the proxy used is $$_javassist - if I get the object (through hibernate) then the object isn't proxied and then JSonWriter can resume the annotation -> so it's able to format as I have annotated –

How to instantiate a class from string FQN in database in hibernate?

I'm trying to convert a legacy application to hibernate.
I have an entity that has a field, which should be instantiated to object instance based on a fully qualified name string in a database.
Consider the example below - if I have somePackageName.FirstClass in a database the someObject field should be an instance of FirstClass.
I guess I could use property access and persist / retrieve a string but that doesn't look very elegant to me.
I cannot use #PostLoad etc. - I'm using pure hibernate with spring (not JPA) - these annotations get ignored.
I know for example in MyBatis one can register a custom handler for field. Would anything similar be available in Hibernate?
I'm new to hibernate so I'm not really sure what the options are.
#Entity
class SomePersistentClass{
private SomeInterface someObject;
}
class FirstClass implements SomeInterface{
}
class SecondClass implements SomeInterface{
}
You can use JPA features such as #PostLoad, etc callbacks simply by enabling the proper Hibernate event listeners. Check the Hibernate EntityManager guide for details.
But this one is even easier. This is the role of a Type in Hibernate. First, you'll have to write an implementation of org.hibernate.type.Type or org.hibernate.usertype.UserType and specify that in #Type( type=... ) that handles the conversions (lots of web resources about writing custom Hibernate types). Then annotate your 'someObject' attribute with #Type( type="your.custom.TypeImpl" )

Can't I use #Value annotation with #Transient annotation?

I have a class to map a table for using hibernate. There are some variable I want to ignore for mapping to use as constant. And I want to load constant value from properties so I code it like this:
#Transient
#Value("${something.value}")
private int MY_VALUE;
But, the value of MY_VALUE is always set to 0. Can't I use #Transient annotation with #Value annotation? Or I missed something else?
Those two annotations belong in different domains.
#Transient belongs to an entity, while #Value belongs to Spring Beans. Entities are managed by JPA / Hibernate, Spring Beans are managed by Spring. It is not a good idea to mix the two.
You could achieve this by using the #Configurable annotation and AspectJ compilation or Load Time Weaving, but I would strongly advise against such a hack. Use a Spring Bean to hold a #Value, not an entity!
You use #Value to specify a property value to load when Spring creates the bean.
However, if you are using Hibernate to load data from a database, Spring is not instantiating these classes for you. So your #Value annotation has no effect.
I would suggest injecting the #Value into the DAO that loads these entities from Hibernate, something like
public class FooDao {
#Value("...")
private int yourConfiguredValue;
public getFoo() {
Foo foo = sessionFactory.getCurrentSession().get(...);
foo.setYourValue(yourConfiguredValue);
return foo;
}
}
In my scenario I have a class Employee which has relation with class Organization.
I don't want to serialize a whole dependent object(Organization), rather serialize a single parameter of organization(e.g. orgID).
I tried following:
#Transient
#value("#{target.orgId.id}")
private UUID org_Id;
but it didnt work. So i used a simple getter mehtod instead of a field variable as follows:
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "orgID")
private Organization orgId;
#JsonProperty("orgId")
public UUID getOrg_ID() {
return orgId.getId();
}
it worked and i got simple orgId field in response serialized by Jackson.
It seems Jackson work with getters without considering a field variable is declared or not corresponding to that getter method.

Categories

Resources