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

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.

Related

Field mapping with MapStruct by JsonProperty annotation

In my current project the names of the model class fields are German. The fields are all annotated with #JsonProperty for the English translation of the names. E.g. #JsonProperty(value = "operation"). Is there a way in the configuration that the mapping of the fields is done using the JsonProperty annotation?
Example:
public class Auftrag {
#JsonProperty(value = "orderType")
private String auftragsart;
...
}
public class OrderDto {
private String orderType;
}
MapStruct uses the Java Bean convention to detect the properties. This means that it looks in the getters and setters.
Out-of-the-box you cannot use the #JsonProperty. However, you can create your own AccessorNamingStrategy that will provide the properties based on #JsonProperty. The AccessorNamingStrategy gives you access to the Abstract syntax tree, which means you can look for fields in types, check their annotations and check their values.
Keep in mind that MapStruct will only ask to get the property for a method, so you would need to get the property name, then find the field in the type, then look for the #JsonProperty annotation and its value.
You can read more about the AccessorNamingStrategy here in the documentation.

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

Is it possible to map a normal Java bean for Hibernate in a separate class / file?

I have a normal model class
public class Person {
private int id;
private String name;
...
}
It's a model class and doesn't have any JPA / Hibernate annotations used.
Is it possible to somehow tell Hibernate to make this class persistent?
I want to use Person in queries, criteria etc, but don't want to introduce annotations to that class (it is defined in a model JAR with no JPA dependency, and I have the DB code in a different JAR);
Hibernate supports XML mappings to map a class to a database, as well as annotations.

#Transient method call in Spring Hibernate

I have one Pojo class in which I create one field which is not mapped with DataBase Table.
So i have to declare the field Declaration and setter and getter method #Transient, otherwise it would have shown an error.
#Transient
private String docHistoryString="";
#Transient
public String getDocHistoryString() {
return docHistoryString;
}
#Transient
public void setDocHistoryString(String docHistoryString) {
this.docHistoryString = docHistoryString;
}
Now, my problem is in the controller. I have set some value in this transient field but when I try to access this variable using EL in view(JSP) it is not giving value. I think this is becouse I used the #transient annotation in get method.
All Hibernate annotations, including #Transient must be applied according to access type. By default it will be the same way as #Id applied. That is if you place #Id on a field you must apply #Transient to the field. And if you apply #Id to getter method, you must apply #Transient method. Setter methods are always ignored.
It can be customized, though (per documentation), so make sure that someone didn't do something strange with access types.
According to this, it should be enough to declare the field/property
http://download.oracle.com/javaee/5/api/javax/persistence/Transient.html
Have you tried with just annotating the field/property? For further Help you have to post some more code snippets.

Hibernate not JPA compliant regarding #Access?

According to my JPA 2.0 book (and online documentation), I should be able to mix field and property access within a single entity or entity hierarchy. The annotation of #Access on the class specifies the default access. When placed on a field or property getter #Access can specify that the default should be overridden for this field.
#Entity
#Access(AccessType.FIELD)
Class Foo {
#Id
int id;
#Column(name = "myfield")
String myField;
#Column(name = "myProp")
#Access(AccessType.PROPERTY)
public int getMyProp () {
return 3;
}
public void setMyProp (int p) {
// do nothing
}
}
This class should result in a table with three columns. However it doesn't with Hibernate...the "myProp" column is missing from the table because apparently Hibernate takes its field vs property cue from the entity ID and runs with it...totally ignoring the JPA spec with regards to #Access.
Can anyone confirm this or did I make a stupid mistake somewhere?
I've seen similar (not the same but similar) issues like HHH-5004 so I wouldn't exclude that this might be a new one (the TCK doesn't seem exhaustive). But what version of Hibernate are you using? Did you try with the latest?
Based on the docs your code seems to be right. The #Access(AccessType.FIELD) annotation on top is unnecessary, because you annotated the field int id;
This tells hibernate to use field access. I tried a very similar example with annotations and xml config mixed. This leads to the same behaviour, so it's probably a bug in hibernate.
I tried with hibernate 3.5.3

Categories

Resources