i am developing some improvements over a legacy system have some quite time
i have a class like this
class MyPersistentClazz
{
private String aTPlace;
public void setATPlace(.......){......}//yes mistyping
#Column(name="atPlaceOrder")
public String getATPlace(){return aTPlace;}
}
they usually load this class using this methods
final MyPersistentClazz clazz = (MyPersistentClazz)session.createCriteria(MyPersistentClazz.class).add(idEq(id)).uniqueResult();
and using load and get methods and works OK.
but the problem arise when i use projections.
final Projection p=Projections.projectionList().add(Projections.property("d.aTPlace"),"aTPlace");
throws
Exception in thread "main" org.hibernate.QueryException: could not resolve property:
my question is...
when using projections i think Hibernate is calling the setter of each property is this assertion OK?
when using criteria.uniqueResult or load or get Hibernate use individual field property access?
or why works with some and not work with others with the same setter?
we are using only annotations not XML.
thanks a lot.
How Hibernate works with your bean depends on how you annotated it. If you annotate instance variables then Hibernate will use direct injection and bypass your Set methods. Otherwise, it will use your Set methods.
Could it be that it is incorrectly converting your property name to a Set method name? Try changing the property name to something simpler (without that series of capital letters), and ensure that the case of the property in your projection is correct.
Related
I'm currently trying to use a binder in Vaadin to access a nested property of an object. After googling a bit I found a reference example which sums up my problem quite well (Original post).:
Assume you have 2 beans:
public class Bean {
private SubBean sub;
// + getter setter
}
public class SubBean {
private String name;
// + getter setter
You think you should be able to do smthing like this:
Binder<Bean> binder = new Binder<>(Bean.class);
binder.bind(new TextField(), "sub.name");
How ever this results in an exception. Following the discussion of Vaadins repository this issue was closed by something called NestedPropertyDefinitions (Potential solution referenced in the issue discussion which lead to closing the issue).
I was looking it up but merely found any information how to use it or how to easily access nested properties with the Vaadin binding system except for this one Documentation.
Can anyone explain to me how to use NestedPropertyDefinitions ?
I found out that this:
binder.forField(new TextField()).bind("sub.name")
works in Vaadin 12.0.7. It does for grids and binders as well. Apparently there is no need to use NestedPropertyDefinitions to achieve nested bindings. I had a bug on my backend side which caused an error that made me assume the binding did not work properly. So I still can't tell if there is another way of achieving this or what NestedPropertyDefinitionsdo but I'd assume that they are used by Vaadin internally.
According to Cashbees comment NestedPropertyDefinitions is only used internally and how to deal with nested properties is indirecetly referenced in this documentation.
Hibernate.custom(userType) is gone in Hibernate 5.2.10.Final so I have to use sessionFactory.getTypeHelper().custom(userType). Is there any way to get TypeHelper without sessionFactory? Previously I was using hibernate 3.6.10.Final. I would rather not use sessionFactory but I can't really find a way around it.
The main goal is to take a org.hibernate.usertype.UserType and return a org.hibernate.type.Type.
I have this function in 3.6.10.Final
public Type getHibernateType() {
// Type is class that implements hibernates UserType
return Hibernate.custom(UserType)
}
in 5.2.10.Final I had to change it to something like
public Type getHibernateType() {
return sessionFactory.getTypeHelper().custom(UserType);
}
I don't really want to use sessionFactory if I can help it. So I was wondering if there was another way to get the Type.
Well, technically 5.2 still exposes the functionality via TypeFactory in a static method.
Type type = TypeFactory.custom( UserType.class, null, null );
However, be aware this method is marked #Deprecated and in fact, that entire class has been removed as a part of Hibernate 6.0's type system overhaul.
I would get used to the notion of using the SessionFactory to access this information because that is precisely how we have designed 6.0 to work at present.
I have interface Resource and several classes implementing it, for example Audio, Video... Further, I have created custom annotation MyAnnotation with Class type param:
#MyAnnotation(type = Audio.class)
class Audio {
...
}
#MyAnnotation(type = Video.class)
class Video{
...
}
In some other place in code I have to use Interface Resource as a returned type:
public class Operations<T extends Resource> {
....
#OtherAnnotation(type = Audio.class (if audio), type = Video.class (if video) )
T getResource();
....
}
The question is how to appropriatelly annotate annotation #OtherAnnotation depending of what kind of Resource type will be returned ?
What you are asking is for dynamic values for annotation attributes.
However annotations can only be set at compile time which is the reason why their values can only be compile time constants. You may only read them at runtime.
There was a similar question in which someone tried to generate the annotation value , it's answer explains why there is no way to dynamically generate a value used in annotation in a bit more detail. In that question there was an attempt to use a final class variable generated with a static method.
There are annotation processors which offer a bit more flexibility by handling placeholders. However i don't think this fits your case, as you want the dynamic values at runtime.
This answer refers to spring's use of the expression language for the Value annotation in which the placeholder (#Value("#{systemProperties.dbName})") gets overrided with the data from one of the property sources defined ( example in spring boot )
In any case, you will have to rethink your architecture a bit.
I have the following class:
class Foo
{
#NotEmpty
private String member1;
#NotEmpty
private String member2;
private String member3; //this one is optional, so has no rules
}
I have a library to which I add all the property names and corresponding UI fields, each time the UI's onChange event occurs, I call validateValue() on the given field name for that field, to validate it and show error/success message.
The problem is, in this case where I have no rules for member3, if I try to validate it by doing this:
String value = event.getValue(); //whatever the new value is now
validator.validateValue(Foo.class, "member3", value);
On the 2nd line, I get the following exception:
Caused by: java.lang.IllegalArgumentException: member3 is not a valid property of
com.xxx.Foo
Both member1 and member2 within the same class, are validated correctly.
Is there anything I can do to avoid getting this exception on the fields that don't have any rules set on them? If not, is there a way (without reflection or specifying it manually for each field) to check if a rule has no rules set on it, so i can avoid calling validateValue on it?
Which version of Hibernate Validator are you using? I checked with the latest version (5.1.0.Final) and there it works. If you can I recommend you upgrade.
You can also create an issue in the Validator issue tracker, reporting your problem and in particular which Validator version you are using.
Last but not least, to answer your question about alternatives. You could use the Bean Validation metadata API to find the constrained properties:
validator.getConstraintsForClass(Foo.class).getConstrainedProperties()
This will allow you to process only the properties which are acually constrained.
When I use JAXB, there is something wrong.
I convert entity to a xml String and everything is ok.
But when I convert xml String back to entity, some information is lost (All of them have the same type java.util.Date).
In entity:
public Date flightBaseDate;
In xml:
<flightBaseDate>2013-09-16T00:00:00 08:00</flightBaseDate>
after unmarshalling, getFlightBaseDate() returns null.
I googled.
Following one suggestion, I used # in my entity.
Then it is:
#XmlElement(name = "timestamp", required = true)
public Date flightBaseDate;
I'm sure it will be perfect,
but...throws Exception, like this:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "flightBaseDate"
this problem is related to the following location:
at public java.lang.String com.wonders.nlia.omms.vo.FlightServiceInfoVo.getFlightBaseDate()
at com.wonders.nlia.omms.vo.FlightServiceInfoVo
this problem is related to the following location:
at public java.lang.String com.wonders.nlia.omms.vo.FlightServiceInfoVo.flightBaseDate
at com.wonders.nlia.omms.vo.FlightServiceInfoVo
Why JAXB could not distinguish between the property and its getMethod?
How to solve it?
Platform:jdk7 win7 eclipse tomcat wtp
My Unmarshalling code is:
JAXBContext context = JAXBContext.newInstance(FlightServiceInfoVo.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
FlightServiceInfoVo flightServiceInfoVo =(FlightServiceInfoVo)unMarshaller.unmarshal(new StringReader(flightServiceInfoVoXml));
flightServiceInfoVoXml is a String.
You can configure JAXB in many different ways. You have chosen Annotations to define the binding (this is allright, do not worry).
I strongle recommend you read about that technique first as there are a lot of pitfalls. Here is a link to a good tutorial. Here is the part in the tutorial which explains why your binding does not work: XmlAccessorType part
As for your specific issue:
In general you have to tell JAXB what and how to bind the java object to it's XML representation. If you do not do anything, then by default all public members of your class are bound (as you can read here).
Additionally you have chosen to annotate the getter method of your public member, which then just pushes the same variable twice to your XML which later causes the exception you see.
To fix your error, either specify a different mapping strategy for your class by putting e.g. (#XmlAccessorType(XmlAccessType.NONE)) before your class declaration or move the annotation from the getter method to the property.
By the way: Having a getter method and a public member variable does not make sense at all. So making your member variable private will also fix your issue with JAXB and be a lot better for your class design.
the exception clearly says that the property name is duplicated, so check you class for a property 'flightBaseDae', it should be unique. remove the duplicate then unmarshall it