I have the following Java Pojo part of an application I am making:
#Document
public class Resume implements ResumePlan,Serializable {
private static final long serialVersionUID = -5332235643191283709L;
#Id
private String id;
#Autowired(required=false)
private Objective objective;
#Autowired
private PersonalDetails personalDetails;
#Autowired
private Skills skills;
#Autowired(required=false)
private Experience experience;
#Autowired
private Education education;
#Autowired(required=false)
private References references;
#Autowired(required=false)
private Publications publications;
}
I am saving it by the following code:
mongoOperations.insert(resume);
When I check on the backend in the mongodb console:
following is getting stored:
db.resume.find();
{ "_id" : "test#abc.com+919876543210", "_class" : "com.springmyresume.resume.Resume" }
It is not storing the rest of the bean objects like PersonalDetails etc..
Can someone tell me what I am doing wrong here.
It is solved. I made the following changes.
1) Removed #Autowired annotation
2) Added #DBRef annotation
With the #Autowired annotation the field objects were not getting saved.
I don't know why this is the behaviour.
First please make sure that you have all necessary fields' classes (Objective, PersonalDetails) annotated as #Document.
For second, please provide getters and setters for fields objects.
Also please make sure, that you have specified actual #Id, otherwise spring will do it for you.
BTW, if you would like to not use embedding, you may use #DBRef annotation. Here is quite good information:
http://maciejwalkowiak.pl/blog/2012/04/30/spring-data-mongodb-cascade-save-on-dbref-objects/
Related
I am currently developing an application within that I am adding a few validations on an inner class such as #NotNull, #Min, #Max, etc.
To make the validations work I need to add the #Valid on each and every field which is making use of the inner class. Is there a way to avoid adding the #Valid on each and every object rather add some annotations on the Class so it can be applicable to all the fields within that class?
I am currently using the following library to achieve the validations:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
I tried to add the #Validated on the class but seems like this annotation is not available in this maven dependency. Can someone please let me know what I need to change?
Following is a simple example that is working but I would like to remove #Valid that I have to add on each field. If I do not add #Valid then those inner classes won't be validated.
public class Book {
#NotNull(message="Book ID cannot be NULL")
private int bookId;
#Valid
private List<Author> author;
#Valid
private List<Publication> author;
}
public class Author {
#NotNull(message="Author ID cannot be NULL")
private int authorID;
#NotNull(message="Author Name cannot be NULL")
private String name;
}
public class Publication {
#NotNull(message="Publication ID cannot be NULL")
private int authorID;
#NotNull(message="Publication Name cannot be NULL")
private String name;
}
There is no way to do what you want to do, except if you write your own Quarkus extension that will add the annotations at build time.
It will be some rather involved work, though, as you will need to add some bytecode transformation to add the annotations where you want them.
Also, you should add the #Valid annotations inside the List e.g. List<#Valid Publication> rather than at the field level. It's more optimized this way.
I want to exclude some of the fields in child entity using jpa.
Ex :
Class Person extends Serializable
{
private String firstName;
private String lastName;
private String id;
private PersonalInformation personalInformation;
}
Class PersonalInformation extends Serializable
{
private Date dob;
private List<PersonalDocument> documents;
}
Class PersonalDocument extends Serializable
{
private String fileName;
private int fileSize;
private byte[] fileData;
}
When I tried to get the details of a person, I could get all the information about a person, including PersonalInformation and PersonalDocument list, but since PersonalDocument.fileData can be huge, every time getting this field from DB is impacting the performance.
So I wanted to ignore/exclude PersonalDocument.fileData field while reading only, I wanted to know how to write the jpa query for the same.
One solution then would be to have the file data lazily fetched i.e. fetched on demand from the database when you access the field. Note that JPA specification does not require that provider implementations actually support the lazy loading of individual fields (rather than associations): any directives in this area can only be considered as a hint to the persistence provider.
I know that Hibernate does support the lazy loading of fields and there are lots of similar questions in this area but I have been unable to find a definitive answer about exactly what is required.
Firstly, however you need to mark the field with the #Lob annotation (http://docs.oracle.com/javaee/6/api/javax/persistence/Lob.html)
import javax.persistence.Lob;
public class PersonalDocument implements Serializable
{
private String fileName;
private int fileSize;
#Basic(fetch=LAZY) //optional??
#Lob
private byte[] fileData;
}
The following suggests that #Lob is lazy by default and so we may not need the additional #Basic(fetch=LAZY) however no harm in adding it anyway.
https://hibernate.atlassian.net/browse/ANN-418
While some similar Stack Overflow questions appear to report that adding #Lob is all that is required to have such fields lazily loaded, the Hibernate docs themselves note that lazy field loading requires byte code enhancement.
https://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/
To enable property level lazy fetching, your classes have to be
instrumented: bytecode is added to the original class to enable such
feature, please refer to the Hibernate reference documentation. If
your classes are not instrumented, property level lazy loading is
silently ignored.
So, in summary:
Add #Lob and see if it works.
If not, add #Basic(fetch=LAZY) and see if it works.
if not, either add byte code enhancement to your build.
https://docs.jboss.org/hibernate/orm/5.0/topical/html/bytecode/BytecodeEnhancement.html
I am using Bean Validation constraints to validate class instances at run time. I have many DTOs where each has multiple fields often with a common constraint. I want to add a constraint to the class so that it applies to all the properties of the class. (As lombok #NotNull constraint).
e.g
class Person {
#NotNull
private String name;
#NotNull
private String address;
#NotNULL
private String contact;
}
I want to make it something like this.
#NotNull
class Person {
private String name;
private String address;
private String contact
}
You cannot do this with plain Bean Validation. So just adding #NotNull to the class won't work.
One potential approach could be to utilize XML configuration. The idea would be to have your own annotation MyNotNull. Your framework would need to scan for these annotations and build the programmatic configuration for the class in question. This could for example be done via a annotation processor during compile time. Once you have the constraint mapping XML files add them to your jar and reference them in validation.xml. That's just a basic idea. Personally, I am not sure whether it is worth the effort.
I know it is not new question in this forum but I am very confused what should i do.
Problem: I am developing one application with spring mvc + hibernate. For server side validation I am using #valid annotation in controller and #null and #notNull annotation in my bean.
e.g
public class User implements Serializable {
private static final long serialVersionUID = 2158419746939747203L;
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long userId;
#Column(name="USERNAME", unique = true)
#NotEmpty #NotNull #Size(min=6, max=20)
private String username;
#Column(name="PASSWORD")
#NotEmpty #NotNull #Size(min=6, max=20)
private String password;
This validation is happening fine and data is also saving in DB.
But I want to validate unique constraint,referential integrity and other constraint using annotation without any validator class.
Is it possible? if no, then what is best and easiest way to to do it(less coding)? I will appreciate if framework will do it for me.
Saurabh,
For unique constraint in table,
#Id
You will be able to enforce referential integrity via hibernate annotations as well
eg.
#OneToOne(mappedBy = "foo")
Here is an example post
Referential integrity with One to One using hibernate
Here is a very detailed tutorial also exploring the same:
http://www.journaldev.com/2882/hibernate-tutorial-for-beginners-using-xml-annotations-and-property-configurations
You could write a "CustomUniqueConstraintValidator" kinda like mentioned in
http://www.journaldev.com/2668/spring-mvc-form-validation-example-using-annotation-and-custom-validator-implementation
You can also pass in paramters from the annotation to the custom validator.
eg.
#CustomValidDate("columnName")
To make a generic class that applies for any field /column
1. YOu can write a generic custom validator
2. use annotaiton parameters (on each class attribute) to pass in the table name and column name.
3. Then in the validator you can use the table name, column name to apply your validation logic (unique etc).
Thanks,
Paul
So, I was banging my head against the monitor for the last 4 hours and can't figure it out.
I am using Dozer for mapping and it works fine. However, I need one of my DAOs in the destination class and autowiring returns null. Here is a snippet of the class:
#Component
public class Address
{
#XmlElement(name = "street", required = true)
protected String street;
#XmlElement(name = "city", required = true)
protected String city;
#XmlElement(name = "zip", required = true)
protected zip;
#Autowired
private CityDao cityDao;
// Getters/setters
}
the cityDao is always null. I am fairly new to both Spring and Dozer, but the Dozer docs say that the destination classes are created with default constructors and as far as I understand the Spring should not have any problems with it. The cityDao is null though. Please help!
As has been mentioned in the comments, you should not be injecting a DAO into a DTO!
However if you absolutely need to do that for some reason, check out Spring's #Configurable support. Here is the Javadoc and also some more information here and here.
If setup correctly, it allows objects that are not explicitly managed by Spring, to benefit from features like auto-wiring dependencies.
In you example code, Address although being annotated with #Component, is not managed by Spring since it's being created using Dozer. That's why you would need #Configurable to inject CityDao into Address