Good day, all. I'm newbie in Spring Data + JPA. And i need your help.
It's my first question on stackoverflow, that sorry if i formed my Question not correct.
I start to realise project using Spring Data + JPA + Hibernate, Spring MVC, Use MySQL.
I have DB scheme:
DB of project
DB scheme
application context:
<context:property-placeholder location="classpath:util.properties" />
<!--Activates various annotations to be detected in bean classes: Spring's #Required and #Autowired and so on-->
<context:annotation-config/>
<!-- Datasource. - MySQL -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}" />
</bean>
<!--Do not forget activate #Transactional JPA annotation with <annotation-driven/>-->
<!-- JPA Persistence Context and EntityManager configuration -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<!--packagesToScan - search Entity and mapping them -->
<property name="packagesToScan" value="by.GetItFree" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
</bean>
<!-- Automatic Transaction Participation-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<jpa:repositories base-package="by.GetItFree.orm.repository" entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"/>
MVC Config:
<!--
mvc:annotation-driven configures Spring MVC annotations
Support for validating #Controller inputs with #Valid, if a JSR-303 Provider is present on the classpath.
HttpMessageConverter support for #RequestBody method parameters and #ResponseBody method return values
from #RequestMapping or #ExceptionHandler methods.
-->
<mvc:annotation-driven/>
<!-- activate #Transactional JPA annotation -->
<tx:annotation-driven/>
<!-- ViewResolver bean config for mapping strings to jsp views -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
<property name="order" value="1" />
<property name="prefix" value="/WEB-INF/view" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:view-controller path="/about.html" view-name="/about/about"/>
<mvc:view-controller path="/index.html" view-name="/index"/>
<!-- Static Resources Configuration (get access to static sources such as CSS and JavaScript files) -->
<mvc:resources mapping="/resources/**" location="/resources/" />
Some of JPA Persistence Entites:
Advert:
#Entity
public class Advert {
private int id;
private String karmaReq;
private byte[] image;
private int profileId;
private String profileUsersUsername;
private String head;
private String content;
private byte ordered;
private Timestamp date;
private Profile profile;
private Collection<Comment> commentsById;
#Id
#Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "karmaReq", nullable = true, length = 45)
public String getKarmaReq() {
return karmaReq;
}
public void setKarmaReq(String karmaReq) {
this.karmaReq = karmaReq;
}
#Basic
#Column(name = "image", nullable = false)
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
#Basic
#Column(name = "profile_id", nullable = false)
public int getProfileId() {
return profileId;
}
public void setProfileId(int profileId) {
this.profileId = profileId;
}
#Basic
#Column(name = "profile_users_username", nullable = false, length = 45)
public String getProfileUsersUsername() {
return profileUsersUsername;
}
public void setProfileUsersUsername(String profileUsersUsername) {
this.profileUsersUsername = profileUsersUsername;
}
#Basic
#Column(name = "head", nullable = true, length = 45)
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
#Basic
#Column(name = "content", nullable = true, length = 450)
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Basic
#Column(name = "ordered", nullable = false)
public byte getOrdered() {
return ordered;
}
public void setOrdered(byte ordered) {
this.ordered = ordered;
}
#Basic
#Column(name = "date", nullable = false)
public Timestamp getDate() {
return date;
}
public void setDate(Timestamp date) {
this.date = date;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Advert advert = (Advert) o;
if (id != advert.id) return false;
if (profileId != advert.profileId) return false;
if (ordered != advert.ordered) return false;
if (karmaReq != null ? !karmaReq.equals(advert.karmaReq) : advert.karmaReq != null) return false;
if (!Arrays.equals(image, advert.image)) return false;
if (profileUsersUsername != null ? !profileUsersUsername.equals(advert.profileUsersUsername) : advert.profileUsersUsername != null)
return false;
if (head != null ? !head.equals(advert.head) : advert.head != null) return false;
if (content != null ? !content.equals(advert.content) : advert.content != null) return false;
if (date != null ? !date.equals(advert.date) : advert.date != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (karmaReq != null ? karmaReq.hashCode() : 0);
result = 31 * result + Arrays.hashCode(image);
result = 31 * result + profileId;
result = 31 * result + (profileUsersUsername != null ? profileUsersUsername.hashCode() : 0);
result = 31 * result + (head != null ? head.hashCode() : 0);
result = 31 * result + (content != null ? content.hashCode() : 0);
result = 31 * result + (int) ordered;
result = 31 * result + (date != null ? date.hashCode() : 0);
return result;
}
#ManyToOne
#JoinColumns({#JoinColumn(name = "profile_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false), #JoinColumn(name = "profile_users_username", referencedColumnName = "users_username", nullable = false, insertable = false, updatable = false)})
public Profile getProfile() {
return profile;
}
public void setProfile(Profile profile) {
this.profile = profile;
}
#OneToMany(mappedBy = "advertByAdvertId")
public Collection<Comment> getCommentsById() {
return commentsById;
}
public void setCommentsById(Collection<Comment> commentsById) {
this.commentsById = commentsById;
}
#Override
public String toString() {
return "Advert{" +
"id=" + id +
", karmaReq='" + karmaReq + '\'' +
", image=" + Arrays.toString(image) +
", profileId=" + profileId +
", profileUsersUsername='" + profileUsersUsername + '\'' +
", head='" + head + '\'' +
", content='" + content + '\'' +
", ordered=" + ordered +
", date=" + date +
", profile=" + profile +
", commentsById=" + commentsById +
'}';
}
}
// I know , that if i comment call profile in to String(), all will be work.
Profile
#Entity
#IdClass(ProfilePK.class)
public class Profile {
private int id;
private String usersUsername;
private Integer karma;
private String phone;
private byte[] icon;
private Collection<Advert> adverts;
private Collection<Comment> comments;
private Collection<Message> messages;
private Users usersByUsersUsername;
#Id
#Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Id
#Column(name = "users_username", nullable = false, length = 45)
public String getUsersUsername() {
return usersUsername;
}
public void setUsersUsername(String usersUsername) {
this.usersUsername = usersUsername;
}
#Basic
#Column(name = "karma", nullable = true)
public Integer getKarma() {
return karma;
}
public void setKarma(Integer karma) {
this.karma = karma;
}
#Basic
#Column(name = "phone", nullable = true, length = 15)
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Basic
#Column(name = "icon", nullable = true)
public byte[] getIcon() {
return icon;
}
public void setIcon(byte[] icon) {
this.icon = icon;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Profile profile = (Profile) o;
if (id != profile.id) return false;
if (usersUsername != null ? !usersUsername.equals(profile.usersUsername) : profile.usersUsername != null)
return false;
if (karma != null ? !karma.equals(profile.karma) : profile.karma != null) return false;
if (phone != null ? !phone.equals(profile.phone) : profile.phone != null) return false;
if (!Arrays.equals(icon, profile.icon)) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (usersUsername != null ? usersUsername.hashCode() : 0);
result = 31 * result + (karma != null ? karma.hashCode() : 0);
result = 31 * result + (phone != null ? phone.hashCode() : 0);
result = 31 * result + Arrays.hashCode(icon);
return result;
}
#OneToMany(mappedBy = "profile")
public Collection<Advert> getAdverts() {
return adverts;
}
public void setAdverts(Collection<Advert> adverts) {
this.adverts = adverts;
}
#OneToMany(mappedBy = "profile")
public Collection<Comment> getComments() {
return comments;
}
public void setComments(Collection<Comment> comments) {
this.comments = comments;
}
#OneToMany(mappedBy = "profile")
public Collection<Message> getMessages() {
return messages;
}
public void setMessages(Collection<Message> messages) {
this.messages = messages;
}
#ManyToOne
#JoinColumn(name = "users_username", referencedColumnName = "username", nullable = false, insertable = false, updatable = false)
public Users getUsersByUsersUsername() {
return usersByUsersUsername;
}
public void setUsersByUsersUsername(Users usersByUsersUsername) {
this.usersByUsersUsername = usersByUsersUsername;
}
#Override
public String toString() {
return "Profile{" +
"id=" + id +
", usersUsername='" + usersUsername + '\'' +
", karma=" + karma +
", phone='" + phone + '\'' +
", icon=" + Arrays.toString(icon) +
", adverts=" + adverts +
", comments=" + comments +
", messages=" + messages +
", usersByUsersUsername=" + usersByUsersUsername +
'}';
}
}
ORM
AdvertDAO
/**
* DAO interface responsible for operation with Advertising.
* <p>
* Created by Novik Igor on 09.02.2017.
*/
public interface AdvertDAO {
/**
* Method returned list of Advert's from the DB.
*
* #return list of Advertising's.
*/
List<Advert> findAll();
/**
* Method returned list of Advert from the DB according ID.
*
* #param head id of the Advert;
* #return Advertising according id.
*/
Advert findByHead(String head);
}
AdvertDAORepository
/**
* SpringData AdvertDAO repository.
*
* Created by Novik Igor on 10.02.2017.
*/
public interface AdvertDAORepository extends CrudRepository<Advert,Integer> {
List<Advert> findByHead(String head);
}
Service for Spring Data/JPA - AdvertDAOImpl
/**
* Repository bean that implements JPA DAO Advert interfaces responsible for operation with Advertising from DB.
* <p>
* Created by nolik on 10.02.17.
*/
#Service("jpaAdvertDAO")
#Repository
#Transactional
public class AdvertDAOImpl implements AdvertDAO {
#Autowired
private AdvertDAORepository advertDAORepository;
#Override
public List<Advert> findAll() {
return Lists.newArrayList(advertDAORepository.findAll());
}
#Override
public Advert findByHead(String head) {
return (Advert) advertDAORepository.findByHead(head);
}
}
Test MVC Controller:
#Controller
public class TestController {
#Autowired
AdvertDAO jpaAdvertDAO;
#Autowired
CommentDAO jpaCommentDAO;
#RequestMapping(value = "/testCall", method = RequestMethod.GET)
public ModelAndView readCookieExample() {
System.out.println(" Test console");
return new ModelAndView("/error/errorpage");
}
#RequestMapping(value = "/jpaFindAllAdvert", method = RequestMethod.GET)
public ModelAndView jpaFindAllAdvert() {
System.out.println("ORMController ormFindAllUsers is called");
List<Advert> adverts = jpaAdvertDAO.findAll();
return new ModelAndView("/error/test", "resultObject", adverts);
}
#RequestMapping(value = "/jpaFindAllComments", method = RequestMethod.GET)
public ModelAndView jpaFindAllComments() {
System.out.println("ORMController FindAllComments is called");
List<Comment> comments = jpaCommentDAO.findAll();
return new ModelAndView("/error/test", "resultObject", comments);
}
}
Simple JSP for showing result of calling "/jpaFindAllAdvert"
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Test</title>
</head>
<body>
<%--Find All Adverts--%>
${resultObject}
</body>
</html>
Firstly i faced with the next exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: by.GetItFree.entities.Profile.adverts, could not initialize proxy - no Session
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:563)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:205)
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:542)
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:133)
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:509)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Profile.toString(Profile.java:144)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Advert.toString(Advert.java:174)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
java.util.AbstractCollection.toString(AbstractCollection.java:462)
org.apache.el.lang.ELSupport.coerceToString(ELSupport.java:497)
org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:529)
org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:47)
javax.el.ELContext.convertToType(ELContext.java:304)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:944)
org.apache.jsp.WEB_002dINF.view.error.test_jsp._jspService(test_jsp.java:118)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1271)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
I google that it's a result of N+1 SQL problem for Hibernate for Leazy initialisation of Joined with #ManyToONe relations.
I use way to fix with adding:
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
to "Jpa Properties"
After this i faced with: StackOverflow exeption:
java.lang.StackOverflowError
java.util.AbstractCollection.toString(AbstractCollection.java:454)
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Profile.toString(Profile.java:144)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Advert.toString(Advert.java:174)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
java.util.AbstractCollection.toString(AbstractCollection.java:462)
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Profile.toString(Profile.java:144)
java.lang.String.valueOf(String.java:2994)
java.lang.StringBuilder.append(StringBuilder.java:131)
by.GetItFree.entities.Advert.toString(Advert.java:174)
Etc.. - very long listing
In Tocat Log in the last case - i see big listing JPQL/or HSQL i'm not shure:
RMController ormFindAllUsers is called
Hibernate: select advert0_.id as id1_1_, advert0_.content as content2_1_, advert0_.date as date3_1_, advert0_.head as head4_1_, advert0_.image as image5_1_, advert0_.karmaReq as karmaReq6_1_, advert0_.ordered as ordered7_1_, advert0_.profile_users_username as profile_9_1_, advert0_.profile_id as profile_8_1_ from Advert advert0_
Hibernate: select profile0_.users_username as users_us1_5_0_, profile0_.id as id2_5_0_, profile0_.icon as icon3_5_0_, profile0_.karma as karma4_5_0_, profile0_.phone as phone5_5_0_, users1_.username as username1_6_1_, users1_.enabled as enabled2_6_1_, users1_.password as password3_6_1_ from Profile profile0_ inner join Users users1_ on profile0_.users_username=users1_.username where profile0_.users_username=? and profile0_.id=?
Hibernate: select adverts0_.profile_users_username as profile_9_1_0_, adverts0_.profile_id as profile_8_1_0_, adverts0_.id as id1_1_0_, adverts0_.id as id1_1_1_, adverts0_.content as content2_1_1_, adverts0_.date as date3_1_1_, adverts0_.head as head4_1_1_, adverts0_.image as image5_1_1_, adverts0_.karmaReq as karmaReq6_1_1_, adverts0_.ordered as ordered7_1_1_, adverts0_.profile_users_username as profile_9_1_1_, adverts0_.profile_id as profile_8_1_1_ from Advert adverts0_ where adverts0_.profile_users_username=? and adverts0_.profile_id=?
Hibernate: select profile0_.users_username as users_us1_5_0_, profile0_.id as id2_5_0_, profile0_.icon as icon3_5_0_, profile0_.karma as karma4_5_0_, profile0_.phone as phone5_5_0_, users1_.username as username1_6_1_, users1_.enabled as enabled2_6_1_, users1_.password as password3_6_1_ from Profile profile0_ inner join Users users1_ on profile0_.users_username=users1_.username where profile0_.users_username=? and profile0_.id=?
My progect on github: ProgectSourceCode
What's the reason of this behaiviour. And what's the solution?
Thx for your attention and support.
The reason you're having this problem is because associations that your view requires should be initialized inside a transaction boundary to avoid the LazyInitializationException. Adding an option to load collections outside of a transaction is merely a bandaid and doesn't truly address the underlying design flaw of your code.
If your view requires that you load Profile and its associated collection of Advert entities, then your either your data access should should specifically toggle that behavior or the query specify that you need that collection initialized.
There are a number of ways you can trigger this collection to be loaded as part of a query.
JPQL/HQL using a JOIN FETCH on the adverts collection.
Specify a join fetch using the Criteria API
Use #FetchProfile to toggle a specific fetch strategy by name.
Use #NamedEntityGraph.
Related
frist of all sorry for my bad english. I am trying to display database (Postgres) rows from one table, and it allways returning null. I am doing project in Java EE using JPA hibernate.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="mesPU">
<class>pl.mes.model.Users</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/test" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="xxxxxx" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/test"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
</properties>
</persistence-unit>
</persistence>
Users entity
package pl.mes.model;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Users {
private Integer userId;
private String firstname;
private String secondname;
private String email;
#Id
#Column(name = "userId", nullable = false)
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
#Basic
#Column(name = "firstname", nullable = true)
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
#Basic
#Column(name = "secondname", nullable = true)
public String getSecondname() {
return secondname;
}
public void setSecondname(String secondname) {
this.secondname = secondname;
}
#Basic
#Column(name = "email", nullable = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Users users = (Users) o;
if (userId != null ? !userId.equals(users.userId) : users.userId != null) return false;
if (firstname != null ? !firstname.equals(users.firstname) : users.firstname != null) return false;
if (secondname != null ? !secondname.equals(users.secondname) : users.secondname != null) return false;
if (email != null ? !email.equals(users.email) : users.email != null) return false;
return true;
}
#Override
public int hashCode() {
int result = userId != null ? userId.hashCode() : 0;
result = 31 * result + (firstname != null ? firstname.hashCode() : 0);
result = 31 * result + (secondname != null ? secondname.hashCode() : 0);
result = 31 * result + (email != null ? email.hashCode() : 0);
return result;
}
}
When i use this
select u from Users u
in console output looks like that:
output
DbSOURCE
I would be grateful if someone can help me with this :)
You have specified the URL jdbc:postgresql://localhost:5432/test for the property javax.persistence.jdbc.url. But when I look at the second screenshot, I can not see a database schema named test.
I guess, you are connecting to the wrong database. Maybe a second instance listening at a different port?
Please also remove the Hibernate specific properties that are already specified by JPA standard properties (as stated out in the comments by Billy Frost).
I have a table called fund, I would like to use JPA in order to write my own queries for it. So, I have use IntelliJ to generate persistence mapping based on my schema and not based on hibernate.
import javax.persistence.*;
import java.sql.Timestamp;
#Entity
#Table(name = "fund", schema = "public", catalog = "db")
public class FundEntity {
private long fundId;
private Timestamp createdAt;
private String description;
private Timestamp modTime;
private String modUser;
private String fundName;
private String fundType;
#Id
#Column(name = "fund_id")
public long getFundId() {
return fundId;
}
public void setFundId(long fundId) {
this.fundId = fundId;
}
#Basic
#Column(name = "created_at")
public Timestamp getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Timestamp createdAt) {
this.createdAt = createdAt;
}
#Basic
#Column(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Basic
#Column(name = "mod_time")
public Timestamp getModTime() {
return modTime;
}
public void setModTime(Timestamp modTime) {
this.modTime = modTime;
}
#Basic
#Column(name = "mod_user")
public String getModUser() {
return modUser;
}
public void setModUser(String modUser) {
this.modUser = modUser;
}
#Basic
#Column(name = "fund_name")
public String getFundName() {
return fundName;
}
public void setFundName(String fundName) {
this.fundName = fundName;
}
#Basic
#Column(name = "fund_type")
public String getFundType() {
return fundType;
}
public void setFundType(String fundType) {
this.fundType = fundType;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FundEntity that = (FundEntity) o;
if (fundId != that.fundId) return false;
if (createdAt != null ? !createdAt.equals(that.createdAt) : that.createdAt != null) return false;
if (description != null ? !description.equals(that.description) : that.description != null) return false;
if (modTime != null ? !modTime.equals(that.modTime) : that.modTime != null) return false;
if (modUser != null ? !modUser.equals(that.modUser) : that.modUser != null) return false;
if (fundName != null ? !fundName.equals(that.fundName) : that.fundName != null) return false;
if (fundType != null ? !fundType.equals(that.fundType) : that.fundType != null) return false;
return true;
}
#Override
public int hashCode() {
int result = (int) (fundId ^ (fundId >>> 32));
result = 31 * result + (createdAt != null ? createdAt.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (modTime != null ? modTime.hashCode() : 0);
result = 31 * result + (modUser != null ? modUser.hashCode() : 0);
result = 31 * result + (fundName != null ? fundName.hashCode() : 0);
result = 31 * result + (fundType != null ? fundType.hashCode() : 0);
return result;
}
}
And this is my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence-unit name="postgres">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5443/db" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="dba" />
<property name="hibernate.connection.password" value="XXX" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.flushMode" value="FLUSH_AUTO" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
Then I try to fetch my funds but with no results:
jpa-ql> select f from FundEntity f
[2016-06-29 18:01:11] FundEntity is not mapped [select f from FundEntity f]
What am I missing here ? I thought the discovery for my entities would be made automatically since I have specified on my persistence.xml file.
If your #Entity class is not in the same classpath as the persistence.xml file, it will not be automatically loaded. For example -
Is there a way to scan JPA entities not to declare persistent classes in a persistence.xml file?
Hibernate is Unable to execute command the table already exit in database.i have comb the whole internet can not figure out what the issue really is . I am new to hibernate anyway below is the scenario. My java files are
Why is hibernate throwing that error? what is the best way to solve this ?
this is my Users.java
#Entity
#Table(name="users")
public class Users {
#Id
#Column(name="USERID")
#GeneratedValue
private int userId;
#Column(name="FULLNAME")
private String fullName;
#Column(name="USERNAME",unique=true, nullable=false)
private String userName;
#Column(name="PASSWORD",nullable=false)
private String passWord;
#Column(name="BANKBRANCH", nullable=false)
private String bankBranch;
#Column(name="DEPARTMENT",nullable=false)
private String department;
#Column(name="ROLEID", unique=true, nullable=false)
private int roleId;
#Column(name="ATMGROUPID" ,unique=true, nullable=false)
private int amtGroupID;
#Column(name="DATECREATED")
private Date dateCreated;
#Column(name="LASTLOGIN")
private Date lastLogin;
#Column(name="USERCREATEDBY")
private String userCreatedBy;
#Column(name="STATE", nullable=false)
private String state=State.ACTIVE.getState();
// #ManyToMany(fetch = FetchType.EAGER)
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "UserRoleStatus",
joinColumns = { #JoinColumn(name = "userId") },
inverseJoinColumns = { #JoinColumn(name = "roleId") })
private Set<UserRoles> UserRoles = new HashSet<UserRoles>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
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 getBankBranch() {
return bankBranch;
}
public void setBankBranch(String bankBranch) {
this.bankBranch = bankBranch;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public int getAmtGroupID() {
return amtGroupID;
}
public void setAmtGroupID(int amtGroupID) {
this.amtGroupID = amtGroupID;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastLogin() {
return lastLogin;
}
public void setLastLogin(Date lastLogin) {
this.lastLogin = lastLogin;
}
public String getUserCreatedBy() {
return userCreatedBy;
}
public void setUserCreatedBy(String userCreatedBy) {
this.userCreatedBy = userCreatedBy;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Set<UserRoles> getUserRoles() {
return UserRoles;
}
public void setUserRoles(Set<UserRoles> userRoles) {
UserRoles = userRoles;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + userId;
result = prime * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
/*if (getClass() != obj.getClass())
return false;*/
if (!(obj instanceof Users))
return false;
Users other = (Users) obj;
if (userId != other.userId)
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
#Override
public String toString() {
return "Users [userId=" + userId + ", fullName=" + fullName + ", userName=" + userName + ", passWord="
+ passWord + ", bankBranch=" + bankBranch + ", department=" + department + ", roleId=" + roleId
+ ", amtGroupID=" + amtGroupID + ", dateCreated=" + dateCreated + ", lastLogin=" + lastLogin
+ ", userCreatedBy=" + userCreatedBy + ", state=" + state + ", UserRoles=" + UserRoles + "]";
}
my usersRoles.Java
#Entity
#Table(name = "USERROLES")
public class UserRoles {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int roleId;
#Column(name="ROLE",length=15, unique=true, nullable=false)
private String role = UserRolesRoles.User.getUserRolesRoles();
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((role == null) ? 0 : role.hashCode());
result = prime * result + roleId;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof UserRoles))
return false;
/*
* if (getClass() != obj.getClass()) return false;
*/
UserRoles other = (UserRoles) obj;
if (roleId != other.roleId)
return false;
if (role == null) {
if (other.role != null)
return false;
} else if (!role.equals(other.role))
return false;
return true;
}
}
my servelet.xml
<context:property-placeholder location="classpath:resources/database.properties" />
<context:component-scan base-package="recon.controller" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<!-- viewResolver tell which viewResolver to use it tell the location of
the view in the project -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources location="/resoures/**" mapping="/resoures/" />
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="recon.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
web.xml
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>15</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Full stack trace
Mar 13, 2016 2:22:41 AM org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException
WARN: GenerationTarget encountered exception accepting command : Unable to execute command [alter table UserRoleStatus add constraint FKon0rvnj31qoi3177vwn868stx foreign key (roleId) references USERROLES (roleId)]
org.hibernate.tool.schema.spi.CommandAcceptanceException: Unable to execute command [alter table UserRoleStatus add constraint FKon0rvnj31qoi3177vwn868stx foreign key (roleId) references USERROLES (roleId)]
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:63)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:567)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:551)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:510)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:309)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:64)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:458)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:864)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:134)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: Can't create table 'G-Recon.#sql-33d9_378' (errno: 150)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:842)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:681)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:51)
... 51 more
Mar 13, 2016 2:22:42 AM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet 'spring-dispatcher': initialization completed in 20634 ms
Mar 13, 2016 2:22:42 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [spring-dispatcher] in context with path [/G_Rcon_Hibernate] threw exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:255)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
mySql Table
CREATE TABLE `UserRoleStatus` (
`userId` bigint(20) UNSIGNED NOT NULL,
`roleId` bigint(20) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `UserRoleStatus` (`userId`, `roleId`) VALUES
(2, 2),
(1, 3);
ALTER TABLE `UserRoleStatus`
ADD PRIMARY KEY (`userId`,`roleId`),
ADD KEY `roleId` (`roleId`),
ADD KEY `userId` (`userId`);
ALTER TABLE `UserRoleStatus`
ADD CONSTRAINT `FKefv8xn71lecn5wv6nfs8leeu1` FOREIGN KEY (`userId`) REFERENCES `users` (`userId`),
ADD CONSTRAINT `UserRoleStatus_ibfk_1` FOREIGN KEY (`roleId`) REFERENCES `userRoles` (`roleId`),
ADD CONSTRAINT `UserRoleStatus_ibfk_2` FOREIGN KEY (`userId`) REFERENCES `users` (`userId`);
At hibernate start-up you can activate a mode for update db, validate entities or create db....
Look in your persistence.xml witch mode you use.
Look for property
hibernate.hbm2ddl.auto
Some more information about this you can find here:
Hbms2ddl
I'm working on a Spring MVC App with JPA (Hibernate as Provider) and a PostgreSQL database. I wanted to insert results (of a time consuming task) into the database in background and created a serviceclass which implements Runnable. In the run method, I receive an entity from the repository but when I try to access a lazy collection of the entity, the database session is already closed (I get a lazy initialization exception).
The source code of my Background-Service:
#Service
#Scope("prototype")
public class ProjectServiceTestThread implements Runnable{
static Logger log = Logger.getLogger(ProjectServiceTestThread.class);
#Autowired
ProjectRepository projectRepository;
#Autowired
ScenarioRepository scenarioRepository;
#Override
#Transactional
public void run() {
List<Project> projectList = projectRepository.findByName("thread test project");
Project project;
project = projectList.get(0);
//A project can have multiple scenarios
Scenario scenario;
if (project.getScenarios().isEmpty()) { //this line fails -> lazyInitializationException - no Session
System.err.println("Creating new scenario");
scenario = new Scenario();
scenario.setName("thread test scenario");
scenario.setDescription(this + ".runServiceFunction at " + System.currentTimeMillis());
scenario.setProject(project);
scenario = scenarioRepository.save(scenario);
} else {
System.err.println("Using existing scenario");
scenario = project.getScenarios().iterator().next();
}
}
}
The Service and Spring TaskExecutor are Autowired in the Controller which is running on a Tomcat v8.0 Server.
Controller code:
#Autowired
ProjectServiceTestThreadImpl testRunnable;
#Autowired
TaskExecutor taskExecutor;
#RequestMapping(value="openproject", method=RequestMethod.GET)
public String getStringProjects(Map<String, Object> model) throws InterruptedException
{
System.err.println(this + " before call to runnable ");
testRunnable.run();
taskExecutor.execute(testRunnable);
return "openproject";
}
The log shows that the database session closes right after the findByName Query:
09:50:31,438 TRACE JdbcCoordinatorImpl:525 - Closing prepared statement [select distinct project0_.prjid as prjid1_24_, project0_.createdby as createdb2_24_, project0_.createdon as createdo3_24_, project0_.description as descript4_24_, project0_.designtarget as designta5_24_, project0_.location as location6_24_, project0_.name as name7_24_, project0_.modelid as modelid11_24_, project0_.timehorizon as timehori8_24_, project0_.updatedby as updatedb9_24_, project0_.updatedon as updated10_24_ from public.project project0_ where lower(project0_.name) like ('%'||lower('thread test project')||'%')]
09:50:31,438 TRACE JdbcCoordinatorImpl:278 - Starting after statement execution processing [ON_CLOSE]
09:50:31,438 TRACE StatefulPersistenceContext:880 - Initializing non-lazy collections
09:50:31,439 TRACE SessionImpl:357 - Closing session
09:50:31,439 TRACE JdbcCoordinatorImpl:199 - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl#3b95a16b]
09:50:31,439 TRACE LogicalConnectionImpl:178 - Closing logical connection
09:50:31,439 DEBUG LogicalConnectionImpl:246 - Releasing JDBC connection
09:50:31,439 DEBUG LogicalConnectionImpl:264 - Released JDBC connection
09:50:31,442 TRACE LogicalConnectionImpl:190 - Logical connection closed
09:50:31,445 TRACE TransactionSynchronizationManager:243 - Removed value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata#7cc8f09] for key [public abstract java.util.List eu.cite.repository.ProjectRepository.findByName(java.lang.String)] from thread [myExecutor-1]
09:50:31,451 TRACE LazyInitializationException:53 - failed to lazily initialize a collection of role: eu.cite.model.Project.scenarios, could not initialize proxy - no Session
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: eu.cite.model.Project.scenarios, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
at org.hibernate.collection.internal.PersistentSet.isEmpty(PersistentSet.java:166)
at eu.cite.service.ProjectServiceTestThread.run(ProjectServiceTestThread.java:73)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Configuration:
<context:component-scan base-package="eu.cite.repository, eu.cite.service" scoped-proxy="targetClass" />
<jpa:repositories base-package="eu.cite.repository" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="punit"/>
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"></property>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<entry key="hibernate.format_sql" value="true"/>
<entry key="hibernate.jdbc.batch_size" value="50"/>
<entry key="hibernate.order_inserts" value="true"/>
</map>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="ModelMapper" class="org.modelmapper.ModelMapper"></bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"></property>
<property name="url" value="jdbc:postgresql://localhost:5432/Cite?autoReconnect=true"></property>
<property name="username" value="cite"></property>
<property name="password" value="***"></property>
</bean>
<task:executor id="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
Can somebody tell me why it does not work this way? I figured out some ways to make it work, but I don't understand why it does not work with the code above. These three approaches correctly insert the Scenario, without closing the database Session in between:
remove #Service from ProjectServiceTestThread and register the bean in the config manually
Not implement Runnable and annotate the run() method of ProjectServiceTestThread with #Async
Not using the Spring Task Executor
Edit - Project entity:
#Entity
#Table(name = "project", schema = "public", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
public class Project implements java.io.Serializable {
private int prjid;
private SimulationModel simulationmodel;
private String name;
private String description;
private String designtarget;
private Date timehorizon;
private String location;
private Date createdon;
private Date updatedon;
private Integer createdby;
private Integer updatedby;
private Set<ObjectiveFunction> objectivefunctions = new HashSet<ObjectiveFunction>(
0);
private Set<Scenario> scenarios = new HashSet<Scenario>(0);
private Set<ScenarioGenerator> scenariogenerators = new HashSet<ScenarioGenerator>(
0);
private List<Component> components = new ArrayList<Component>();
private Set<OptConstraint> optconstraints = new HashSet<OptConstraint>(0);
private Set<SearchConstraint> searchconstraints = new HashSet<SearchConstraint>(
0);
private Set<Metric> metrics = new HashSet<Metric>(0);
private Set<UserGroupProject> usergroupprojects = new HashSet<UserGroupProject>(
0);
private Set<ExtParam> extparams = new HashSet<ExtParam>(0);
public Project() {
}
public Project(int prjid, String name) {
this.prjid = prjid;
this.name = name;
}
public Project(int prjid, SimulationModel simulationmodel, String name,
String description, String designtarget, Date timehorizon, String location,
Date createdon, Date updatedon, Integer createdby,
Integer updatedby, Set<ObjectiveFunction> objectivefunctions,
Set<Scenario> scenarios, Set<ScenarioGenerator> scenariogenerators,
List<Component> components, Set<OptConstraint> optconstraints,
Set<SearchConstraint> searchconstraints, Set<Metric> metrics,
Set<UserGroupProject> usergroupprojects, Set<ExtParam> extparams) {
this.prjid = prjid;
this.simulationmodel = simulationmodel;
this.name = name;
this.description = description;
this.designtarget = designtarget;
this.timehorizon = timehorizon;
this.location = location;
this.createdon = createdon;
this.updatedon = updatedon;
this.createdby = createdby;
this.updatedby = updatedby;
this.objectivefunctions = objectivefunctions;
this.scenarios = scenarios;
this.scenariogenerators = scenariogenerators;
this.components = components;
this.optconstraints = optconstraints;
this.searchconstraints = searchconstraints;
this.metrics = metrics;
this.usergroupprojects = usergroupprojects;
this.extparams = extparams;
}
#SequenceGenerator(name="project_prjid_seq",sequenceName="project_prjid_seq") #GeneratedValue(strategy = GenerationType.SEQUENCE, generator="project_prjid_seq")
#Id
#Column(name = "prjid", unique = true, nullable = false)
public int getPrjid() {
return this.prjid;
}
public void setPrjid(int prjid) {
this.prjid = prjid;
}
#ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.PERSIST)
#JoinColumn(name = "modelid")
public SimulationModel getSimulationmodel() {
return this.simulationmodel;
}
public void setSimulationmodel(SimulationModel simulationmodel) {
this.simulationmodel = simulationmodel;
}
#Column(name = "name", unique = true, nullable = false, length = 50)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "description")
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "designtarget", length = 50)
public String getDesigntarget() {
return this.designtarget;
}
public void setDesigntarget(String designtarget) {
this.designtarget = designtarget;
}
#Temporal(TemporalType.TIME)
#Column(name = "timehorizon", length = 15)
public Date getTimehorizon() {
return this.timehorizon;
}
public void setTimehorizon(Date timehorizon) {
this.timehorizon = timehorizon;
}
#Column(name = "location")
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "createdon", length = 22)
public Date getCreatedon() {
return this.createdon;
}
public void setCreatedon(Date createdon) {
this.createdon = createdon;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updatedon", length = 22)
public Date getUpdatedon() {
return this.updatedon;
}
public void setUpdatedon(Date updatedon) {
this.updatedon = updatedon;
}
#Column(name = "createdby")
public Integer getCreatedby() {
return this.createdby;
}
public void setCreatedby(Integer createdby) {
this.createdby = createdby;
}
#Column(name = "updatedby")
public Integer getUpdatedby() {
return this.updatedby;
}
public void setUpdatedby(Integer updatedby) {
this.updatedby = updatedby;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<ObjectiveFunction> getObjectivefunctions() {
return this.objectivefunctions;
}
public void setObjectivefunctions(Set<ObjectiveFunction> objectivefunctions) {
this.objectivefunctions = objectivefunctions;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<Scenario> getScenarios() {
return this.scenarios;
}
public void setScenarios(Set<Scenario> scenarios) {
this.scenarios = scenarios;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<ScenarioGenerator> getScenariogenerators() {
return this.scenariogenerators;
}
public void setScenariogenerators(Set<ScenarioGenerator> scenariogenerators) {
this.scenariogenerators = scenariogenerators;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
#OrderBy("componentid")
public List<Component> getComponents() {
return this.components;
}
public void setComponents(List<Component> components) {
this.components = components;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<OptConstraint> getOptconstraints() {
return this.optconstraints;
}
public void setOptconstraints(Set<OptConstraint> optconstraints) {
this.optconstraints = optconstraints;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<SearchConstraint> getSearchconstraints() {
return this.searchconstraints;
}
public void setSearchconstraints(Set<SearchConstraint> searchconstraints) {
this.searchconstraints = searchconstraints;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<Metric> getMetrics() {
return this.metrics;
}
public void setMetrics(Set<Metric> metrics) {
this.metrics = metrics;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<UserGroupProject> getUsergroupprojects() {
return this.usergroupprojects;
}
public void setUsergroupprojects(Set<UserGroupProject> usergroupprojects) {
this.usergroupprojects = usergroupprojects;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
public Set<ExtParam> getExtparams() {
return this.extparams;
}
public void setExtparams(Set<ExtParam> extparams) {
this.extparams = extparams;
}
I found the issue in my appConfig.java: There was another component scan, which scanned all packages, including services:
#Configuration
#EnableWebMvc
#ComponentScan({"eu.cite"})
public class appConfig extends WebMvcConfigurerAdapter {
this seems to undo the transaction configuration from the xml. I changed the component scan to eu.cite.controller so my servlet is still able to find the controller and does not interfere with the other config
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>