I am writing a Java project that uses Hibernate ORM and Spring Framework. Right now, when I add a POJO class, I need to modify my hibernate.cfg.xml file, which looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="somepackage.class1"/>
<mapping class="somepackage.class2"/>
<!-- etc. -->
</session-factory>
</hibernate-configuration>
Then, I create an annotation-based class. I heard that I could avoid adding per-class mappings in hibernate.cfg.xml if I used proper Hibernate annotations. How can I modify a class to avoid the mappings in an XML file? Here is my example POJO file, generated by NetBeans:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package somepackage.pojo;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author D
*/
#Entity
#Table(name = "ACCOUNT")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Account.findAll", query = "SELECT a FROM Account a"),
#NamedQuery(name = "Account.findByLogin", query = "SELECT a FROM Account a WHERE a.login = :login"),
#NamedQuery(name = "Account.findByPassword", query = "SELECT a FROM Account a WHERE a.password = :password")})
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
#Column(name = "LOGIN", nullable = false, length = 100)
private String login;
#Size(max = 128)
#Column(name = "PASSWORD", length = 128)
private String password;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "author")
private Collection<Comment> commentCollection;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "author")
private Collection<Article> articleCollection;
public Account() {
}
public Account(String login) {
this.login = login;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#XmlTransient
public Collection<Comment> getCommentCollection() {
return commentCollection;
}
public void setCommentCollection(Collection<Comment> commentCollection) {
this.commentCollection = commentCollection;
}
#XmlTransient
public Collection<Article> getArticleCollection() {
return articleCollection;
}
public void setArticleCollection(Collection<Article> articleCollection) {
this.articleCollection = articleCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (login != null ? login.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Account)) {
return false;
}
Account other = (Account) object;
if ((this.login == null && other.login != null) || (this.login != null && !this.login.equals(other.login))) {
return false;
}
return true;
}
#Override
public String toString() {
return "somepackage.pojo.Account[ login=" + login + " ]";
}
}
I'd suggest you export the hibernate configuration to the spring configuration because of the flexibility that spring provides. Your concern is to not declare the class in the configuration every time you create a new entity. Using spring configuration you can do the following. (packagestoscan property)
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.baeldung.spring.persistence.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
Ref: http://www.javacodegeeks.com/2013/05/hibernate-3-with-spring.html
Related
guys please help me for solve this error, it's been 4 days, this problem hasn't been solved.
this is my Entity Class code :
package mybengkel;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
*
* #author rhmtsaepuloh
*/
#Entity
#Table(name = "employee")
#NamedQueries({
#NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e"),
#NamedQuery(name = "Employee.findById", query = "SELECT e FROM Employee e WHERE e.id = :id"),
#NamedQuery(name = "Employee.findByUsername", query = "SELECT e FROM Employee e WHERE e.username = :username"),
#NamedQuery(name = "Employee.findByPassword", query = "SELECT e FROM Employee e WHERE e.password = :password")})
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "username")
private String username;
#Basic(optional = false)
#Column(name = "password")
private String password;
public Employee() {
}
public Employee(Integer id) {
this.id = id;
}
public Employee(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Employee)) {
return false;
}
Employee other = (Employee) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "mybengkel.Employee[ id=" + id + " ]";
}
}
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MyBengkelPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<jar-file>/Users/rhmtsaepuloh/Downloads/mysql-connector-java-8.0.18/mysql-connector-java-8.0.18.jar</jar-file>
<class>mybengkel.Employee</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/oop?serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
and Main class java :
package mybengkel;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
*
* #author rhmtsaepuloh
*/
public class MyBengkel {
public static void main(String[] args) {
EntityManager em;
EntityManagerFactory emf;
emf = Persistence.createEntityManagerFactory("MyBengkelPU");
em = emf.createEntityManager();
em.getTransaction().begin();
Employee e = new Employee();
e.setUsername("haha");
e.setPassword("hehe");
em.persist(e);
em.getTransaction().commit();
}
}
the problem is when I run the program found error code :
[EL Info]: 2019-11-28 16:07:45.916--ServerSession(347978868)--EclipseLink, version: Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd
[EL Info]: connection: 2019-11-28 16:07:46.813--ServerSession(347978868)--file:/Volumes/Data/Perkuliahan/OOP/NetBeans/MyBengkel/build/classes/_MyBengkelPU login successful
[EL Warning]: metamodel: 2019-11-28 16:07:46.859--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
Exception in thread "main" java.lang.IllegalArgumentException: Object: mybengkel.Employee[ id=null ] is not a known entity type.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4228)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
at mybengkel.MyBengkel.main(MyBengkel.java:29)
/Users/rhmtsaepuloh/Library/Caches/NetBeans/11.1/executor-snippets/run.xml:111: The following error occurred while executing this line:
/Users/rhmtsaepuloh/Library/Caches/NetBeans/11.1/executor-snippets/run.xml:68: Java returned: 1
BUILD FAILED (total time: 3 seconds)
I try this on netbeans 11.1 and mysql connector java 8.0.18 Please help me to fix it guys... Thanks before
I am creating a website using Spring MVC and for persistence I am using Spring Data JPA with Hibernate 4 as my JPA provider. Validation is being handled at present with Hibernate Validator. I have a problem whereby my validators are being called twice and I can't figure out why. The main reason this is a problem is because the second time round, dependencies are not being autowired into the validator and I am getting a null pointer exception.
The following is the sequence of calls leading up to the failure:
The registration form is submitted and first the NotDefaultSectValidator is called and completes successfully for the 'whereDidYouHearAboutUs' field on the user object.
The UniqueUsernameValidator is called next and completes successfully for the 'username' field validation.
The 'addUserFromForm' method on the controller starts and finds no errors in the bindingResults object.
The 'addUser' method is then called on the UserService class. This method reaches the line 'userRepository.save(user);' but never then runs the 'print.ln' line immediate afterwards. Stepping over this line takes be back to the 'NotDefaultSectValidator' breakpoint. This completes for the second time and I re-enter the second validator 'UniqueUsernameValidator '. Here I get a null pointer exception because for some reason Spring fails to Autowire in the DAO this second time.
Can anyone shed light on why the validators are being called twice and in particular, why stepping over line 'userRepository.save(user);' goes back into these validators?
Many thanks
Here is my user.java class
package com.dating.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.joda.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import com.dating.annotation.NotDefaultSelect;
import com.dating.annotation.UniqueUsername;
#Entity
#Table(name = "dating.user")
public class User {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "username", unique = true)
#NotEmpty
#Pattern(regexp = "^[a-zA-Z0-9]*$")
#UniqueUsername
private String username;
#Column(name = "password", nullable = false)
#NotEmpty
#Size(min = 8)
private String password;
#Column(name = "first_name", nullable = false)
#NotEmpty
private String firstName;
#Column(name = "last_name", nullable = false)
#NotEmpty
private String lastName;
#Transient
private String fullName;
#Column(name = "email", nullable = false)
#NotEmpty
#Email
private String email;
#Column(name = "gender", nullable = false)
#NotEmpty
private String gender;
#Column(name = "date_of_birth", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
#DateTimeFormat(pattern = "dd/MM/yyyy")
private LocalDate dateOfBirth;
#Column(name = "join_date", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate joinDate;
#Column(name = "where_did_you_hear_about_us", nullable = false)
#NotDefaultSelect
private String whereDidYouHearAboutUs;
#Column(name = "enabled")
private boolean enabled;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "dating.user_roles", joinColumns = { #JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { #JoinColumn(name = "role_id", nullable = false, updatable = false) })
private Set<Role> roles = new HashSet<Role>();
#Column(name = "created_time", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate createdTime;
#Column(name = "modification_time", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate modificationTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFullName() {
return firstName + " " + lastName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public LocalDate getJoinDate() {
return joinDate;
}
public void setJoinDate(LocalDate joinDate) {
this.joinDate = joinDate;
}
public String getWhereDidYouHearAboutUs() {
return whereDidYouHearAboutUs;
}
public void setWhereDidYouHearAboutUs(String whereDidYouHearAboutUs) {
this.whereDidYouHearAboutUs = whereDidYouHearAboutUs;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public void addRole(Role role) {
roles.add(role);
}
public LocalDate getCreatedTime() {
return createdTime;
}
public void setCreatedTime(LocalDate createdTime) {
this.createdTime = createdTime;
}
public LocalDate getModificationTime() {
return modificationTime;
}
public void setModificationTime(LocalDate modificationTime) {
this.modificationTime = modificationTime;
}
#PreUpdate
public void preUpdate() {
modificationTime = new LocalDate();
}
#PrePersist
public void prePersist() {
LocalDate now = new LocalDate();
createdTime = now;
modificationTime = now;
}
}
The relevant method in my registration controller:
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String addUserFromForm(#Valid User user,
BindingResult bindingResult, RedirectAttributes ra) {
if (bindingResult.hasErrors()) {
return "user/register";
}
userService.addUser(user);
// Redirecting to avoid duplicate submission of the form
return "redirect:/user/" + user.getUsername();
}
My service class:
package com.dating.service.impl;
import javax.transaction.Transactional;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.dating.domain.Role;
import com.dating.domain.User;
import com.dating.repository.RoleRepository;
import com.dating.repository.UserRepository;
import com.dating.repository.specification.UserSpecifications;
import com.dating.service.UserService;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Transactional
#Override
public void addUser(User user) {
user.setJoinDate(new LocalDate());
user.setEnabled(true);
Role role = roleRepository.findByName(Role.MEMBER);
if (role == null) {
role = new Role();
role.setName(Role.MEMBER);
}
user.addRole(role);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
user.setPassword(encoder.encode(user.getPassword()));
userRepository.save(user);
System.out.println("User Saved");
}
#Override
public User getUserByUsername(String username) {
return userRepository.findByUsername(username);
}
#Override
public Iterable<User> getAllUsers() {
return userRepository.findAll();
}
#Override
public void updateDetails(User user) {
userRepository.save(user);
}
#Override
public Iterable<User> lastNameIsLike(String searchTerm) {
return userRepository.findAll(UserSpecifications
.lastNameIsLike(searchTerm));
}
}
My NotDefaultSelect validator:
package com.dating.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.dating.annotation.NotDefaultSelect;
public class NotDefaultSelectValidator implements
ConstraintValidator<NotDefaultSelect, String> {
#Override
public void initialize(NotDefaultSelect constraint) {
}
#Override
public boolean isValid(String selectedValue, ConstraintValidatorContext ctx) {
if (selectedValue == null) {
return false;
}
if (selectedValue.equals("") || selectedValue.equals("0")
|| selectedValue.equalsIgnoreCase("default")
|| selectedValue.equalsIgnoreCase("please select")) {
return false;
}
return true;
}
}
My uniqueUsername validator:
package com.dating.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.dating.annotation.UniqueUsername;
import com.dating.repository.UserRepository;
public class UniqueUsernameValidator implements
ConstraintValidator<UniqueUsername, String> {
#Autowired
private UserRepository userRepository;
#Override
public void initialize(UniqueUsername constraint) {
}
#Override
public boolean isValid(String username, ConstraintValidatorContext ctx) {
if (username == null || userRepository.findByUsername(username) == null) {
return true;
}
return false;
}
}
My UserRepository:
package com.dating.repository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import com.dating.domain.User;
//Spring Data JPA Marker interfaces being extended for automatic CRUD repository creation
public interface UserRepository extends CrudRepository<User, Long>, JpaSpecificationExecutor<User> {
//Automatic query creation from method name
public User findByUsername(String username);
}
Lastly my persistence-context.xml file
<!-- Data source properties -->
<util:properties id="dataSourceSettings" location="classpath:datasource.properties" />
<!-- Pooled data source using BoneCP -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
destroy-method="close">
<property name="driverClass" value="#{dataSourceSettings['jdbc.driverClass']}" />
<property name="jdbcUrl" value="#{dataSourceSettings['jdbc.url']}" />
<property name="username" value="#{dataSourceSettings['jdbc.username']}" />
<property name="password" value="#{dataSourceSettings['jdbc.password']}" />
<property name="idleConnectionTestPeriodInMinutes" value="60" />
<property name="idleMaxAgeInMinutes" value="240" />
<property name="maxConnectionsPerPartition" value="30" />
<property name="minConnectionsPerPartition" value="10" />
<property name="partitionCount" value="3" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
<!-- JPA entity manager factory bean -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.dating.domain" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">#{dataSourceSettings['hibernate.dialect']}</prop>
<prop key="hibernate.hbm2ddl.auto">#{dataSourceSettings['hibernate.hbm2ddl.auto']}
</prop>
<prop key="hibernate.show_sql">#{dataSourceSettings['hibernate.show_sql']}</prop>
<prop key="hibernate.format_sql">#{dataSourceSettings['hibernate.format_sql']}</prop>
<prop key="hibernate.use_sql_comments">#{dataSourceSettings['hibernate.use_sql_comments']}
</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:annotation-config />
<jpa:repositories base-package="com.dating.repository"/>
Maybe the second validation is done by hibernate when you are sending your bean to the datastore. To turn it off add this to your persistence.xml:
<property name="javax.persistence.validation.mode" value="none"/>
https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/configuration.html says:
By default, Bean Validation (and Hibernate Validator) is activated. When an entity is created, updated (and optionally deleted), it is validated before being sent to the database. The database schema generated by Hibernate also reflects the constraints declared on the entity.
You can fine-tune that if needed:
AUTO: if Bean Validation is present in the classpath, CALLBACK and DDL are activated.
CALLBACK: entities are validated on creation, update and deletion. If no Bean Validation provider is present, an exception is raised at initialization time.
DDL: (not standard, see below) database schemas are entities are validated on creation, update and deletion. If no Bean Validation provider is present, an exception is raised at initialization time.
NONE: Bean Validation is not used at all
The first one is obviously done by your Spring controller because of #Valid annotation.
You can just add this property in your application.property files to disable hibernate validation spring.jpa.properties.javax.persistence.validation.mode=none
I've got a problem. I spend over one hour searching through the Internet but I did find nothing....
I have a simple Table class and one of its elements is List of java.util.Date. When I run the program, the exception is shown:
> org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany
> targeting an unmapped class:
> com.model.Time.timetable[java.util.Date].
My config file:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3036/test
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hbm2ddl.auto">create</property>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.model.Cinema" />
<mapping class="com.model.Time" />
</session-factory>
</hibernate-configuration>
and my class:
package com.model;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import info.talacha.filmweb.models.Movie;
#Entity
#Table(name = "Time")
public class Time implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private int id;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "time_id")
private List<Date> timetable;
#Column(name = "movie")
private Movie movie;
#Column(name = "dubbing")
private boolean dubbing;
#Column(name = "subtitles")
private boolean subtitles;
#Column(name = "threeDimensions")
private boolean threeDimensions;
public Time(){
timetable = new ArrayList<Date>();
dubbing= false;
subtitles = false;
threeDimensions = false;
movie = new Movie();
}
public Time(int id, List<Date> timetable, Movie movie, boolean dubbing, boolean subtitles, boolean is3dMovie) {
super();
this.id = id;
this.timetable = timetable;
this.movie = movie;
this.dubbing = dubbing;
this.subtitles = subtitles;
threeDimensions = is3dMovie;
}
public boolean isThreeDimensions() {
return threeDimensions;
}
public void setThreeDimensions(boolean threeDimensions) {
this.threeDimensions = threeDimensions;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Movie getMovie() {
return movie;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
public Time(List<Date> timetable, Movie movie,boolean dubbing, boolean subtitles,boolean is3D) {
this.timetable = timetable;
this.dubbing = dubbing;
this.subtitles = subtitles;
this.movie = movie;
this.threeDimensions = is3D;
}
public List<Date> getTimetable() {
return timetable;
}
public void setTimetable(List<Date> timetable) {
this.timetable = timetable;
}
public boolean isDubbing() {
return dubbing;
}
public void setDubbing(boolean dubbing) {
this.dubbing = dubbing;
}
public boolean isSubtitles() {
return subtitles;
}
public void setSubtitles(boolean subtitles) {
this.subtitles = subtitles;
}
#Override
public String toString() {
return "Time [timetable=" + timetable + ", movie=" + movie + ", dubbing=" + dubbing + ", subtitles="
+ subtitles + ", is3DMovie=" + threeDimensions + "]";
}
}
This way of mapping (oneToMany) worked great when I used it for different type... I have no idea what's wrong. I tried few things but they didn't work. I will be grateful for your help!
OneToMany is used to create an association between two entities. java.util.Date is not an entity. It's a basic type. What you want is #ElementCollection.
Try usin #Temporal annotation like this:
#Temporal(value = TemporalType.TIMESTAMP)
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "time_id")
private List<Date> timetable;
Try Date attribut from java.sql.Date to define each Date attributs of the Time class.
See you.
I am creating a website using Spring MVC and for persistence I am using Spring Data JPA with Hibernate 4 as my JPA provider. Validation is being handled at present with Hibernate Validator. I have a problem whereby my validators are being called twice and I can't figure out why. The main reason this is a problem is because the second time round, dependencies are not being autowired into the validator and I am getting a null pointer exception.
The following is the sequence of calls leading up to the failure:
The registration form is submitted and first the NotDefaultSectValidator is called and completes successfully for the 'whereDidYouHearAboutUs' field on the user object.
The UniqueUsernameValidator is called next and completes successfully for the 'username' field validation.
The 'addUserFromForm' method on the controller starts and finds no errors in the bindingResults object.
The 'addUser' method is then called on the UserService class. This method reaches the line 'userRepository.save(user);' but never then runs the 'print.ln' line immediate afterwards. Stepping over this line takes be back to the 'NotDefaultSectValidator' breakpoint. This completes for the second time and I re-enter the second validator 'UniqueUsernameValidator '. Here I get a null pointer exception because for some reason Spring fails to Autowire in the DAO this second time.
Can anyone shed light on why the validators are being called twice and in particular, why stepping over line 'userRepository.save(user);' goes back into these validators?
Many thanks
Here is my user.java class
package com.dating.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.joda.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import com.dating.annotation.NotDefaultSelect;
import com.dating.annotation.UniqueUsername;
#Entity
#Table(name = "dating.user")
public class User {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "username", unique = true)
#NotEmpty
#Pattern(regexp = "^[a-zA-Z0-9]*$")
#UniqueUsername
private String username;
#Column(name = "password", nullable = false)
#NotEmpty
#Size(min = 8)
private String password;
#Column(name = "first_name", nullable = false)
#NotEmpty
private String firstName;
#Column(name = "last_name", nullable = false)
#NotEmpty
private String lastName;
#Transient
private String fullName;
#Column(name = "email", nullable = false)
#NotEmpty
#Email
private String email;
#Column(name = "gender", nullable = false)
#NotEmpty
private String gender;
#Column(name = "date_of_birth", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
#DateTimeFormat(pattern = "dd/MM/yyyy")
private LocalDate dateOfBirth;
#Column(name = "join_date", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate joinDate;
#Column(name = "where_did_you_hear_about_us", nullable = false)
#NotDefaultSelect
private String whereDidYouHearAboutUs;
#Column(name = "enabled")
private boolean enabled;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "dating.user_roles", joinColumns = { #JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { #JoinColumn(name = "role_id", nullable = false, updatable = false) })
private Set<Role> roles = new HashSet<Role>();
#Column(name = "created_time", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate createdTime;
#Column(name = "modification_time", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate modificationTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFullName() {
return firstName + " " + lastName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public LocalDate getJoinDate() {
return joinDate;
}
public void setJoinDate(LocalDate joinDate) {
this.joinDate = joinDate;
}
public String getWhereDidYouHearAboutUs() {
return whereDidYouHearAboutUs;
}
public void setWhereDidYouHearAboutUs(String whereDidYouHearAboutUs) {
this.whereDidYouHearAboutUs = whereDidYouHearAboutUs;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public void addRole(Role role) {
roles.add(role);
}
public LocalDate getCreatedTime() {
return createdTime;
}
public void setCreatedTime(LocalDate createdTime) {
this.createdTime = createdTime;
}
public LocalDate getModificationTime() {
return modificationTime;
}
public void setModificationTime(LocalDate modificationTime) {
this.modificationTime = modificationTime;
}
#PreUpdate
public void preUpdate() {
modificationTime = new LocalDate();
}
#PrePersist
public void prePersist() {
LocalDate now = new LocalDate();
createdTime = now;
modificationTime = now;
}
}
The relevant method in my registration controller:
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String addUserFromForm(#Valid User user,
BindingResult bindingResult, RedirectAttributes ra) {
if (bindingResult.hasErrors()) {
return "user/register";
}
userService.addUser(user);
// Redirecting to avoid duplicate submission of the form
return "redirect:/user/" + user.getUsername();
}
My service class:
package com.dating.service.impl;
import javax.transaction.Transactional;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.dating.domain.Role;
import com.dating.domain.User;
import com.dating.repository.RoleRepository;
import com.dating.repository.UserRepository;
import com.dating.repository.specification.UserSpecifications;
import com.dating.service.UserService;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Transactional
#Override
public void addUser(User user) {
user.setJoinDate(new LocalDate());
user.setEnabled(true);
Role role = roleRepository.findByName(Role.MEMBER);
if (role == null) {
role = new Role();
role.setName(Role.MEMBER);
}
user.addRole(role);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
user.setPassword(encoder.encode(user.getPassword()));
userRepository.save(user);
System.out.println("User Saved");
}
#Override
public User getUserByUsername(String username) {
return userRepository.findByUsername(username);
}
#Override
public Iterable<User> getAllUsers() {
return userRepository.findAll();
}
#Override
public void updateDetails(User user) {
userRepository.save(user);
}
#Override
public Iterable<User> lastNameIsLike(String searchTerm) {
return userRepository.findAll(UserSpecifications
.lastNameIsLike(searchTerm));
}
}
My NotDefaultSelect validator:
package com.dating.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.dating.annotation.NotDefaultSelect;
public class NotDefaultSelectValidator implements
ConstraintValidator<NotDefaultSelect, String> {
#Override
public void initialize(NotDefaultSelect constraint) {
}
#Override
public boolean isValid(String selectedValue, ConstraintValidatorContext ctx) {
if (selectedValue == null) {
return false;
}
if (selectedValue.equals("") || selectedValue.equals("0")
|| selectedValue.equalsIgnoreCase("default")
|| selectedValue.equalsIgnoreCase("please select")) {
return false;
}
return true;
}
}
My uniqueUsername validator:
package com.dating.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.dating.annotation.UniqueUsername;
import com.dating.repository.UserRepository;
public class UniqueUsernameValidator implements
ConstraintValidator<UniqueUsername, String> {
#Autowired
private UserRepository userRepository;
#Override
public void initialize(UniqueUsername constraint) {
}
#Override
public boolean isValid(String username, ConstraintValidatorContext ctx) {
if (username == null || userRepository.findByUsername(username) == null) {
return true;
}
return false;
}
}
My UserRepository:
package com.dating.repository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import com.dating.domain.User;
//Spring Data JPA Marker interfaces being extended for automatic CRUD repository creation
public interface UserRepository extends CrudRepository<User, Long>, JpaSpecificationExecutor<User> {
//Automatic query creation from method name
public User findByUsername(String username);
}
Lastly my persistence-context.xml file
<!-- Data source properties -->
<util:properties id="dataSourceSettings" location="classpath:datasource.properties" />
<!-- Pooled data source using BoneCP -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
destroy-method="close">
<property name="driverClass" value="#{dataSourceSettings['jdbc.driverClass']}" />
<property name="jdbcUrl" value="#{dataSourceSettings['jdbc.url']}" />
<property name="username" value="#{dataSourceSettings['jdbc.username']}" />
<property name="password" value="#{dataSourceSettings['jdbc.password']}" />
<property name="idleConnectionTestPeriodInMinutes" value="60" />
<property name="idleMaxAgeInMinutes" value="240" />
<property name="maxConnectionsPerPartition" value="30" />
<property name="minConnectionsPerPartition" value="10" />
<property name="partitionCount" value="3" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
<!-- JPA entity manager factory bean -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.dating.domain" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">#{dataSourceSettings['hibernate.dialect']}</prop>
<prop key="hibernate.hbm2ddl.auto">#{dataSourceSettings['hibernate.hbm2ddl.auto']}
</prop>
<prop key="hibernate.show_sql">#{dataSourceSettings['hibernate.show_sql']}</prop>
<prop key="hibernate.format_sql">#{dataSourceSettings['hibernate.format_sql']}</prop>
<prop key="hibernate.use_sql_comments">#{dataSourceSettings['hibernate.use_sql_comments']}
</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:annotation-config />
<jpa:repositories base-package="com.dating.repository"/>
Maybe the second validation is done by hibernate when you are sending your bean to the datastore. To turn it off add this to your persistence.xml:
<property name="javax.persistence.validation.mode" value="none"/>
https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/configuration.html says:
By default, Bean Validation (and Hibernate Validator) is activated. When an entity is created, updated (and optionally deleted), it is validated before being sent to the database. The database schema generated by Hibernate also reflects the constraints declared on the entity.
You can fine-tune that if needed:
AUTO: if Bean Validation is present in the classpath, CALLBACK and DDL are activated.
CALLBACK: entities are validated on creation, update and deletion. If no Bean Validation provider is present, an exception is raised at initialization time.
DDL: (not standard, see below) database schemas are entities are validated on creation, update and deletion. If no Bean Validation provider is present, an exception is raised at initialization time.
NONE: Bean Validation is not used at all
The first one is obviously done by your Spring controller because of #Valid annotation.
You can just add this property in your application.property files to disable hibernate validation spring.jpa.properties.javax.persistence.validation.mode=none
I'm trying to figure out how to use #PersistenceUnit as I've read it's a much better solution than #PersistenceContext. The trouble is.... I can't figure out how to get it to work properly...
#Controller
public class Content {
#PersistenceUnit(unitName = "CMTPU")
public EntityManagerFactory emf;
public EntityManager em = emf.createEntityManager();
#RequestMapping(value={"/content/edit*"}, method=RequestMethod.GET)
public ModelAndView edit(Model model) {
ModelAndView mv = new ModelAndView();
mv.setViewName("content/edit");
//get symbols
List<Symbol> symbols = em.createNamedQuery("Symbol.findAll").getResultList();
mv.addObject(symbols);
return mv;
}
}
My app loaded before I added the //get symbols section and the EntityManager stuff. Now I'm seeing the error SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NullPointerException
I've read that I need to define a unitName, but then I'm looking at this documentation and it doesn't show that being done.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CMTPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>CMT_DEV</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
I'm having trouble determining what I'm doing wrong.
update
My model defines the database and all of that as seen below. Do I even need a persistence.xml?
package com.fettergroup.cmt.models;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
#Entity
#Table(name = "symbol", catalog = "DATABASE1", schema = "dbo")
#NamedQueries({
#NamedQuery(name = "Symbol.findAll", query = "SELECT s FROM Symbol s"),
#NamedQuery(name = "Symbol.findById", query = "SELECT s FROM Symbol s WHERE s.id = :id"),
#NamedQuery(name = "Symbol.findBySymbol", query = "SELECT s FROM Symbol s WHERE s.symbol = :symbol"),
#NamedQuery(name = "Symbol.findByHtmlNumber", query = "SELECT s FROM Symbol s WHERE s.htmlNumber = :htmlNumber"),
#NamedQuery(name = "Symbol.findByHtmlName", query = "SELECT s FROM Symbol s WHERE s.htmlName = :htmlName"),
#NamedQuery(name = "Symbol.findByAsciiDec", query = "SELECT s FROM Symbol s WHERE s.asciiDec = :asciiDec"),
#NamedQuery(name = "Symbol.findByAsciiHex", query = "SELECT s FROM Symbol s WHERE s.asciiHex = :asciiHex")})
public class Symbol implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Short id;
#Size(max = 10)
#Column(name = "symbol")
private String symbol;
#Size(max = 10)
#Column(name = "html_number")
private String htmlNumber;
#Size(max = 10)
#Column(name = "html_name")
private String htmlName;
#Size(max = 10)
#Column(name = "ascii_dec")
private String asciiDec;
#Size(max = 10)
#Column(name = "ascii_hex")
private String asciiHex;
public Symbol() {
}
public Symbol(Short id) {
this.id = id;
}
public Short getId() {
return id;
}
public void setId(Short id) {
this.id = id;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getHtmlNumber() {
return htmlNumber;
}
public void setHtmlNumber(String htmlNumber) {
this.htmlNumber = htmlNumber;
}
public String getHtmlName() {
return htmlName;
}
public void setHtmlName(String htmlName) {
this.htmlName = htmlName;
}
public String getAsciiDec() {
return asciiDec;
}
public void setAsciiDec(String asciiDec) {
this.asciiDec = asciiDec;
}
public String getAsciiHex() {
return asciiHex;
}
public void setAsciiHex(String asciiHex) {
this.asciiHex = asciiHex;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Symbol)) {
return false;
}
Symbol other = (Symbol) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.project1.models.Symbol[ id=" + id + " ]";
}
}
use only
#Controller
public class Content {
#PersistenceContext(unitName = "CMTPU")
public EntityManager em;
The entity manager should be controlled by spring.
This ins an example, it uses hiberante as persistence provider, but I think you can adapt it.
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="myPersistenceUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
</bean>
</property>
</bean>
sample persistance unit, that works with that configuration
<persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>