Hibernate Annotations : No default constructor for entity - java

I am trying to persist the objects generated by JAXB. Here is the sample structure:
#Column(name = "reporting_identifier")
private String reportingIdentifier;
#Column(name = "apply_quiet_time")
private boolean applyQuietTime;
#Embedded
private RecipientDetailsList recipientDetailsList;
Below is the structure of RecipientDetailsList class:
#ElementCollection(targetClass=String.class)
private List<RecipientDetails> recipientDetails;
Now, the RecipientDetails class has one argument constructor, which accepts a String. That String I want to persist in the database as a part of the whole record. I am seeing
org.hibernate.InstantiationException: No default constructor for entity: RecipientDetailsList
exception when I try to save an object. I have two questions:
Do we have any work around this exception? I can't change the class as it is designed for JAXB marshalling/unmarhsalling. Can I somehow store the objects without altering the structure? Also, I am interested in only storing the first record of the list referenced by
recipientDetails as I want only one row for object. I want it to ignore the rest of the records if it has more than 1 record. Is it possible?
Is this good design to use the annotation directly into classes which are generated by JAXB? Should I create another classes (and possibly mappers/converters) just to store and retrieve the information?

For your first question: this is happening because when Hibernate tries to create a bean, it does it via reflection. It does the object creation by calling the no-arg constructor, and then using the setter methods to set the properties. You can't use a bean that doesn't have a no-arg constructor.
For the second question: if something else has generated classes for you that don't have a no-arg constructor, really your only option (if you can't modify the class) is to create a wrapper round it, or a subclass that has a no-arg constructor. I don't see any other way of doing it if you can't modify the class directly. But the subclassing should be fine as long as the class you've got has enough visibility on the methods (i.e., doesn't have private methods that you then can't get to).

Related

How to Inject values from a property file into JSR Custom Annotation

I have a spring component that validates the values of an Entity Class,
One of the variables has a Custom Annotation whose values are supposed to be loaded from the property file, currently it says that Attribute must be constant
Here is the sample code.
I know that Spring allows to fetch properties like this
#Value("${allowedNames}")
private String names;
But I have an entity with one of the variables annotated by custom validator interface i.e. #NameValidationDefinition. I would like to pass the values from the properties file to the annotation but it gives compile time error that Attribute must be Constant which I understand as I know that
Annotations take only constants or final and static declared primitives or Strings
public Class Person {
#NameValidationDefinition(values = names)
private String name;
}
What I want to know is that is there a workaround for this to make it work?
The value from the properties file is by default casted to String but still when I create the Entity and initialize the variable as static final and pass the String in the Constructor, I get the same compile time error.
I would appreciate any kind of help on this.
You cannot have variables in annotations. That's not a limitation of Bean Validation, but of the JVM itself. See also Which types can be used for Java annotation members?
Note, in the Spring example you are giving the value is a string with a special "key" ${allowedNames} which later on gets interpolated. That's different from the value of the annotation being an actual variable as your code implies.

Combining xmelements with constructor

I have a class order which has 3 fields: id, name and showing-id.
I have a xml-file with orders and reading them worked perfect.
However, I made a constructor for Order and now it doesn't work anymore.
How can I have a constructor and xml-elementbinding at the same time?
JAXB requires a no-arg constructor. You should be able to provide one (try marking it private) and things should work.
If the object isn't the root one, then you could also create an object with a default constructor and use an XmlAdapter to convert to/from it to avoid having to add the no-arg constructor to your domain object (see linked article below for an example).
http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html

Convert POJO to JavaFX Property

In my project, I have a number of POJOs whose fields are shown in a JavaFX GUI. I currently update the UI using a manual refresh – whenever the POJO changes, I call a refresh() method. I would like to attempt using binding to accomplish this instead, which requires using JavaFX properties. Whilst I can change the object, its internal fields are other objects, which I cannot change (they are populated using GSON, which AFAIK uses 'normal' Java objects – e.g. String, not StringProperty). Furthermore, the object is read only – it only has getters, not setters.
I believe I can use a ReadOnlyJavaBeanObjectPropertyBuilder (yay Java naming?) or a ReadOnlyObjectWrapper to wrap the object as a property. However, the internal fields – which are what I want to bind the Labels to – are not converted to properties. Is there any way of doing such a recursive conversion – convert an entire object which contains normal object fields into a property which contains further properties? Is this even necessary – am I doing something wrong?
EDIT: I suspect any solution would have to use reflection.
I'm not sure but have a look at BeanPathAdapter
Its part of JFXtras-Labs, downloadable jar.
Source is here on GitHub.
How about adapters for the POJOs?
Example
public class Person{
private String name;
private Address addr;
\\getters, setters...
}
And for the JavaFX GUI
public class FXPerson{
public FXPerson(Person p){
this.name = \\build StringProperty
this.fxaddr = \\build ObjectProperty<FXAddress>
}
private StringProperty name;
private ObjectProperty<FXAddress> fxaddr;
}
Downside:
For every POJO you will have to write an adapter. And if a POJO changes (e.g. new property etc.) you will need to update the corresponding adapter.

mapping superclasses and subclasses with hibernate (JPA)

I am trying to persist objects in a database using hibernate JPA.
The objects already have a type hierarchy, and I'm trying to make it work with hibernate.
A CatalogPackage object has all the important properties and all the getters.
A CatalogPackageImpl (extends CatalogPackage) object has no properties, but most of the setters.
Both classes are non-abstract.
We want code to refer to CatalogPackage objects. But when initializing hibernate, it complains about the setters missing from the CatalogPackage class.
How do I suggest to hibernate that it use the subclass when building the objects?
I don't want to move all the setters to the superclass, and I don't want to use CatalogPackageImpl as the entity.
Even though I can't see the problem with defining the setter methods in your CatalogPackage since they can be marked private to avoid using them from external world.
Since you didn't paste your entities configuration and that you say Hibernate is complaining about the setter methods I can conclude you are using your getters to describe your entity mapping, right?
In such a case Hibernate will always still complaining because it assumes anything mapped to the database should be done in both directions, if it can read from the datastorage so it should be allowed to write in there.
SO you have either of below solutions:
Add the setters modifiers.
Move the mapping from getter methods to fields and set the acces type to field on top of your entity:
#Access(AccessType.Field)
class CatalogPackage {
...
}

Is it possible to have immutable fields in Hibernate/JPA?

In our application, we need to have fields that are assignable only once.
At first we thought of encapsulating the fields and making the setters private. However, some questions arouse:
Without a public setter, is Hibernate still able to map the field from the database?
Can I strip out the setter and make the field mutable only in the entity constructor?
Finally, is there any standard JPA way to make a field immutable?
Thanks in advance.
Try
#Column(updatable = false)
And make your setter private. (Leave your getter public if you want)
I think this is the best practice.
P.S.: JPA uses field access if you annotate your fields and uses getter/setter access if you annotate your getter method.
Ad. 1: I believe JPA uses plain private fields for both read and write if annotations are placed on fields and not on getters. Recently I discovered that Hibernate as an underlying JPA provider does not even need get*() and set*() methods at all. This was truly enlightening solution since from the beginning I thought Hibernate needs accessors. So the answer is: you don't need setters as far as Hibernate is concerned.
Ad. 2: However please note that Hibernate still needs no-arg constructor, otherwise it will fail to load entities with a descriptive exception. This is also a JPA requirement.
Ad. 3: No, there isn't. Remember that your collections would also had to be immutable.
Try
#Column(updatable = false)
From javadoc:
Whether the column is included in SQL UPDATE statements generated by
the persistence provider.
In JPA 2.0 you have two ways to define what attributes should be persisted:
Access(FIELD) - the fields name are persisted,
Access(PROPERTY) - the properties name are persisted.
If no Access(-) annotation is used, the decision what access will be used depends on where you put your #Id annotation. If you put it next to your field - Access(FIELD) will be used. If you put it next to your accessor - Access(PROPERTY) will be used.
Therefore, if you use Access(FIELD) you don't have to have an appropriate JavaBeans-style accessor for particular field. You can have a private field named 'myField' and a public setter for it named 'public setBlahBlah(-)'. The JPA will persist just the 'myField'.
You can mark an entity with #Entity(mutable=false) or #Immutable annotations for the framework to make use of this fact for performance gain in caching and such. (Hibernate)
Then you can use an immutable wrapper class like this:
public class ImmutableStuff {
private final FooField barValue;
public ImmutableStuff(Stuff stuff) {
barValue = stuff.barValue;
}
public FooField getBarValue(){
return barValue;
}
}

Categories