I'm fairly new to Spring and I've been using this tutorial to help me build #ManyToMany relationships. I'm trying to make a ManyToMany relationship between User and Role and then another ManyToMany relationship between Role and Permission. I've followed the article throughout and I seem to be getting this error and cannot figure out why it's happening.
Note: I am using Gradle, not Maven; I don't know if that makes any difference. I am also using perisistence with org.springframework.data.repository.CrudRepository.
Stacktrace
2016-06-23 11:35:17.312 ERROR 7389 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:701)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:688)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:678)
Exception in thread "main" at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:273)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:971)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:960)
at AdeyTrack.AdeyTrackApplication.main(AdeyTrackApplication.java:30)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: AdeyTrack.domain.Permissions; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy85.save(Unknown Source)
at AdeyTrack.AdeyTrackApplication.createRoleIfNotFound(AdeyTrackApplication.java:112)
at AdeyTrack.AdeyTrackApplication.run(AdeyTrackApplication.java:76)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:698)
... 7 common frames omitted
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:470)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:295)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
at com.sun.proxy.$Proxy78.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:439)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:452)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:437)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:409)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:701)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:688)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:678)
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:273)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:971)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:960)
at AdeyTrack.AdeyTrackApplication.main(AdeyTrackApplication.java:30)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: AdeyTrack.domain.Permissions; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy85.save(Unknown Source)
at AdeyTrack.AdeyTrackApplication.createRoleIfNotFound(AdeyTrackApplication.java:112)
at AdeyTrack.AdeyTrackApplication.run(AdeyTrackApplication.java:76)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
... 7 more at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 17 common frames omitted
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:470)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:295)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
at com.sun.proxy.$Proxy78.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:439)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:452)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:437)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:409)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 17 more
ApplicationRunner:
package AdeyTrack;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import AdeyTrack.domain.Role;
import AdeyTrack.domain.Permissions;
import AdeyTrack.domain.User;
import AdeyTrack.persistence.repository.PermissionsRepository;
import AdeyTrack.persistence.repository.RoleRepository;
import AdeyTrack.persistence.repository.UserRepository;
#SpringBootApplication
public class AdeyTrackApplication implements ApplicationRunner {
boolean setup = false;
public static void main(String[] args) {
SpringApplication.run(AdeyTrackApplication.class, args);
}
#Autowired
private UserRepository userRepo;
#Autowired
private PermissionsRepository permRepo;
#Autowired
private RoleRepository roleRepo;
#Override
public void run(ApplicationArguments args) throws Exception {
BCryptPasswordEncoder pe = new BCryptPasswordEncoder();
if(setup){ return ; }
/* Create permissions */
Permissions edit_store = createPermissionsIfNotFound(Permission.STORE.PERM_STORE_EDIT.name(), "edit a store");
Permissions create_store = createPermissionsIfNotFound(Permission.STORE.PERM_STORE_CREATE.name(), "create a store");
List<Permissions> adminPermissions = Arrays.asList(edit_store, create_store);
/* Create roles */
createRoleIfNotFound("STORE_ADMIN", adminPermissions);
createRoleIfNotFound("STORE_EDITOR", Arrays.asList(create_store));
Role adminRole = roleRepo.findByRole("STORE_ADMIN");
Role editRole = roleRepo.findByRole("STORE_EDITOR");
User storeadmin = new User("storeadmin", pe.encode("password"));
User storeedit = new User("storeedit", pe.encode("password"));
storeadmin.setRoles(Arrays.asList(adminRole));
storeedit.setRoles(Arrays.asList(editRole));
userRepo.save(storeadmin);
// userRepo.save(storeedit);
setup = true;
}
#Transactional
private Permissions createPermissionsIfNotFound(String name, String description){
Permissions permission = permRepo.findByPermission(name);
if(permission == null){
permission = new Permissions(name, description);
permRepo.save(permission);
}
return permission;
}
#Transactional
private Role createRoleIfNotFound(String name, Collection<Permissions> permissions) {
Role role = roleRepo.findByRole(name);
if (role == null) {
role = new Role(name);
role.setPermissions(permissions);
roleRepo.save(role);
}
return role;
}
}
User.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="users")
public class User {
#Id
#GeneratedValue
private Integer id;
private String login;
private String password;
private boolean enabled;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="users_roles",
joinColumns = {#JoinColumn(name="user_id", referencedColumnName="id")},
inverseJoinColumns = {#JoinColumn(name="role_id", referencedColumnName="id")}
)
private Collection<Role> roles = new ArrayList<>();
public User(){
super();
}
public User(String login, String password){
super();
this.login = login;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> role) {
this.roles = role;
}
public void setRole(Role role) {
this.roles.add(role);
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Role.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
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.Table;
#Entity
#Table(name="roles")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String role;
#ManyToMany(mappedBy = "roles")
private Collection<User> users;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="role_permissions",
joinColumns = {#JoinColumn(name="role_id", referencedColumnName="id")},
inverseJoinColumns = {#JoinColumn(name="permission_id", referencedColumnName="id")}
)
private Collection<Permissions> rolePermissions;
public Role(){
super();
}
public Role(String role){
super();
this.role = role;
}
public Role(String role, Collection<Permissions> permissions){
super();
this.role = role;
this.rolePermissions = permissions;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public void setUsers(Collection<User> users){
if(users.size() == 1){
this.users = users;
} else if(users.size() > 1){
this.users.addAll(users);
}
}
public Collection<User> getUsers(){
return users;
}
public void setPermissions(Collection<Permissions> permissions){
this.rolePermissions = permissions;
}
public Collection<Permissions> getPermissions(){
return rolePermissions;
}
}
Permission.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
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.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="permissions")
public class Permissions {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToMany(mappedBy = "rolePermissions", cascade = CascadeType.ALL)
private Collection<Role> roles;
private String permission;
private String description;
public Permissions(){
super();
}
public Permissions(String permission, String description){
super();
this.permission = permission;
this.description = description;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Collection<Role> getRole() {
return roles;
}
public void setRole(Collection<Role> role) {
this.roles = role;
}
public String getPermission(){
return permission;
}
public void setPermission(String permission){
this.permission = permission;
}
public String getDescription(){
return description;
}
public void setDescription(String description){
this.description = description;
}
}
Any help would be appreciated.
By using #Transactional, many important aspects such as transaction propagation are handled automatically. In this case if another transactional method is called by businessLogic(), that method will have the option of joining the ongoing transaction.
#Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}
One potential downside is that this powerful mechanism hides what is going on under the hood, making it hard to debug when things don't work.
One of the key points about #Transactional is that there are two separate concepts to consider, each with it's own scope and life cycle:
the persistence context
the database transaction
The transactional annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of a persistence context.
The persistence context is in JPA the EntityManager, implemented internally using an Hibernate Session (when using Hibernate as the persistence provider).
The persistence context is just a synchronizer object that tracks the state of a limited set of Java objects and makes sure that changes on those objects are eventually persisted back into the database.
This is a very different notion than the one of a database transaction. One Entity Manager can be used across several database transactions, and it actually often is.
So I feel extremely stupid because the whole issue lies in the Application runner. After doing a little bit more digging around I discovered that it is vital to use #Transactional in the run method, I have no clue why this is the case but just adding that annotation has fixed everything for some reason.
Related
I am trying to retrieve data from 2 tables in MySql using spring boot and hibernate #OneToMany bi-directional mapping. But am getting this error among others:
No identifier specified for entity: com.dafe.spring.applogger.entity.Action
Please Check the error trace below:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-03-14 18:56:59.251 ERROR 8200 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity: com.dafe.spring.applogger.entity.Action
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.13.RELEASE.jar:2.1.13.RELEASE]
at com.dafe.spring.applogger.AppLoggerApplication.main(AppLoggerApplication.java:10) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_161]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.13.RELEASE.jar:2.1.13.RELEASE]
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.dafe.spring.applogger.entity.Action
at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:266) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:211) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:775) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:250) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:231) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:274) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1215) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1246) ~[hibernate-core-5.3.15.Final.jar:5.3.15.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) ~[spring-orm-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1830) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1767) ~[spring-beans-5.1.14.RELEASE.jar:5.1.14.RELEASE]
... 21 common frames omitted
the class the error is pointing to is below but I don't seem to know what the problem is. Find below is the com.dafe.spring.applogger.entity.Action class :
package com.dafe.spring.applogger.entity;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.springframework.data.annotation.Id;
#Entity
#Table(name="action")
public class Action {
//declare & annotate your fields
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="time")
private Timestamp logTime;
#Column(name="type")
private String logType;
#Column(name="log_id")
private int userLogId;
#ManyToOne
#JoinColumn(name="log_id")
private UserLog userLog;
public Action(int id, Timestamp logTime, String logType, int userLogId, UserLog userLog) {
this.id = id;
this.logTime = logTime;
this.logType = logType;
this.userLogId = userLogId;
this.userLog = userLog;
}
//create and generate constructor
public Action() {
}
public Action(Timestamp logTime, String logType, int userLogId) {
this.logTime = logTime;
this.logType = logType;
this.userLogId = userLogId;
}
//generate getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Timestamp getLogTime() {
return logTime;
}
public void setLogTime(Timestamp logTime) {
this.logTime = logTime;
}
public String getLogType() {
return logType;
}
public void setLogType(String logType) {
this.logType = logType;
}
public int getLogId() {
return userLogId;
}
public void setLogId(int logId) {
this.userLogId = logId;
}
public UserLog userLog() {
return userLog;
}
public void setLogs(UserLog userLog) {
this.userLog = userLog;
}
//generate toString
#Override
public String toString() {
return "Action [id=" + id + ", logTime=" + logTime + ", logType=" + logType + ", userLogId=" + userLogId + "]";
}
}
The action class is supposed to fetch data from database and has a foreign key relationship with class UserLog.
package com.dafe.spring.applogger.entity;
import java.util.ArrayList;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="log")
public class UserLog {
//define field
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="user_id")
private String userId;
#Column(name="session_id")
private String sessionId;
#OneToMany(mappedBy="log",cascade=CascadeType.ALL)
private ArrayList<Action>action;
//define constructors
public UserLog(String userId, String sessionId) {
this.userId = userId;
this.sessionId = sessionId;
}
//define getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public ArrayList<Action> getAction() {
return action;
}
public void setAction(ArrayList<Action> action) {
this.action = action;
}
//convenience method for Action
public void addAction(Action tempAction) {
if (action == null) {
action = new ArrayList<>();
}
action.add(tempAction);
}
//define toString
#Override
public String toString() {
return "Log [id=" + id + ", userId=" + userId + ", sessionId=" + sessionId + "]";
}
}
please help me figure out the problem and a possible solution. Thanks.
You have imported the Id from the wrong package.This error can be thrown when you import a different library for #Id than javax.persistance.Id ;
So change
import org.springframework.data.annotation.Id;
To
import javax.persistence.Id
Refer this thread
I think an issue is related to this mapping:
#OneToMany(mappedBy="log",cascade=CascadeType.ALL)
private ArrayList<Action>action;
mappedBy points to the name of the property on the 'owning' side. So in your case you should specify mappedBy="userLog" as it's defined in Action class
#ManyToOne
#JoinColumn(name="log_id")
private UserLog userLog;
I am new to Jpa and hibernate.I tried to use #ManytoMany mapping in jpa and used the class as:
User.java
package com.jpa.manytomany.manytomany.model;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
#Entity
public class User {
#Id
#GeneratedValue
private Long id;
#NotNull
#Size(max = 100)
#Column(unique = true)
private String userName;
#NotNull
#Size(max=100)
#Column(unique = true)
private String password;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name="user_role",joinColumns=#JoinColumn(name="user_id"),
inverseJoinColumns = #JoinColumn(name="role_id"))
private List<Role> roles;
public User() {
}
public User(String userName, String password) {
this.userName = userName;
this.password = password;
}
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 List<Role> getRoles() {
return roles;
}
public void setRoles(Role role) {
this.roles.add(role);
}
}
Role.java
package com.jpa.manytomany.manytomany.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
#Entity
public class Role {
#Id
#GeneratedValue
private Long id;
#NotNull
private String roleName;
#ManyToMany(mappedBy = "roles")
private List<User> users=new ArrayList<>();
public Role() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Role(String roleName) {
this.roleName = roleName;
}
public List<User> getUsers() {
return users;
}
public void setUsers(User user) {
this.users.add(user);
}
}
I have used auto table generator properties of hibernate and it generated as:
I write a test case to insert the data into these three tables as:
package com.jpa.manytomany.manytomany;
import com.jpa.manytomany.manytomany.model.Role;
import com.jpa.manytomany.manytomany.model.User;
import com.jpa.manytomany.manytomany.repository.RoleRepository;
import com.jpa.manytomany.manytomany.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ManytomanyApplicationTests {
private Logger logger= LoggerFactory.getLogger(this.getClass());
#Autowired
private RoleRepository roleRepository;
#Autowired
private UserRepository userRepository;
#Test
public void insert_into_three_tables() {
User user=new User("Ashwin","password1");
Role role=new Role("ROLE_ADMIN");
userRepository.insertUserAndRole(user,role);
}
}
UserRepository is:
package com.jpa.manytomany.manytomany.repository;
import com.jpa.manytomany.manytomany.model.Role;
import com.jpa.manytomany.manytomany.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
#Repository
#Transactional
public class UserRepository {
private Logger logger= LoggerFactory.getLogger(this.getClass());
#Autowired
private EntityManager entityManager;
public void insertUserAndRole(User user, Role role) {
user.setRoles(role);
role.setUsers(user);
entityManager.persist(user);
entityManager.persist(role);
}
}
RoleRepository is:
package com.jpa.manytomany.manytomany.repository;
import com.jpa.manytomany.manytomany.model.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
#Repository
#Transactional
public class RoleRepository {
#Autowired
private EntityManager em;
public Role insertRole(Role role){
em.persist(role);
return role;
}
}
The error I am getting is :
java.lang.NullPointerException
at com.jpa.manytomany.manytomany.model.User.setRoles(User.java:70)
at com.jpa.manytomany.manytomany.repository.UserRepository.insertUserAndRole(UserRepository.java:29)
at com.jpa.manytomany.manytomany.repository.UserRepository$$FastClassBySpringCGLIB$$63f7afd9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.jpa.manytomany.manytomany.repository.UserRepository$$EnhancerBySpringCGLIB$$2a8fc203.insertUserAndRole(<generated>)
at com.jpa.manytomany.manytomany.ManytomanyApplicationTests.insert_into_three_tables(ManytomanyApplicationTests.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
The role needs to be initialized using a List
private List<Role> roles= new ArrayList<Role>();
Whenever you have List<> in you models , you have to initialize them in the constructor of your domain
even if you dont override your constructor , in this case you have to override and initilize Lists of the model
Like :
In the fields you have :
Private List<Role> roles;
then in the constructor you have :
this.roles = new Arraylist<>;
My database has two table. One of University, another is Faculty. They are one to many relationship
package server.hibernate.domain;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
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.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Version;
#Entity
#Table(name = "UNIVERSITY")
public class University implements Serializable{
private Long _id;
private int _version;
private String _universityName;
private String _countryLocated;
private Set<Faculty> _faculties = new HashSet<Faculty>();
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ID")
public Long getId() {
return _id;
}
public void setId(Long _id) {
this._id = _id;
}
#Version
#Column(name = "VERSION")
public int getVersion() {
return _version;
}
public void setVersion(int _version) {
this._version = _version;
}
#Column(name = "UNIVERSITY_NAME", nullable=false)
public String getUniversityName() {
return _universityName;
}
public void setUniversityName(String _universityName) {
this._universityName = _universityName;
}
#Column(name = "COUNTRY_LOCATED")
public String getCountryLocated() {
return _countryLocated;
}
public void setCountryLocated(String _countryLocated) {
this._countryLocated = _countryLocated;
}
#OneToMany(mappedBy="university", targetEntity=Faculty.class, orphanRemoval=true, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public Set<Faculty> getFaculties() {
return _faculties;
}
public void setFaculties(Set<Faculty> faculties) {
this._faculties = faculties;
}
public String toString(){
return new String("UniversityID:"+_id
+ " UniversityName:"+_universityName
+" CountryLocated:"+_countryLocated);
}
}
This is what I have set in University class.
package server.hibernate.domain;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
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.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Version;
#Entity
#Table(name="FACULTY")
public class Faculty implements Serializable{
private Long _id;
private int _version;
private String _facultyName;
private String _deanName;
private University _university;
private Set<Student> _students = new HashSet<Student>();
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ID")
public Long getId() {
return _id;
}
public void setId(Long id) {
this._id = id;
}
#Version
#Column(name = "VERSION")
public int getVersion() {
return _version;
}
public void setVersion(int version) {
this._version = version;
}
#Column(name="FACULTY_NAME", nullable=false)
public String getFacultyName() {
return _facultyName;
}
public void setFacultyName(String facultyName) {
this._facultyName = facultyName;
}
#Column(name="DEAN_NAME")
public String getDeanName() {
return _deanName;
}
public void setDeanName(String dean_name) {
this._deanName = dean_name;
}
#ManyToOne
#JoinColumn(name = "UNIVERSITY_ID", nullable=false)
public University getUniversity() {
return _university;
}
public void setUniversity(University university) {
this._university = university;
}
#OneToMany(mappedBy="faculty", targetEntity=Student.class, orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
public Set<Student> getStudents() {
return _students;
}
public void setStudents(Set<Student> students) {
this._students = students;
}
public String toString(){
return new String("FacultyID:"+_id
+" FacultyName:"+_facultyName
+" DeanName:"+_deanName);
}
}
This is my faculty class
But when I use sessionFactory.delete(university). I still have this exception
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not delete: [server.hibernate.domain.University#1]; SQL [delete from UNIVERSITY where ID=? and VERSION=?]; constraint ["FKE9B72644368E5BBD: PUBLIC.FACULTY FOREIGN KEY(UNIVERSITY_ID) REFERENCES PUBLIC.UNIVERSITY(ID)"; SQL statement:
delete from UNIVERSITY where ID=? and VERSION=? [23503-160]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [server.hibernate.domain.University#1]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy19.removeUniversity(Unknown Source)
at main.TestHibernateMain.test(TestHibernateMain.java:73)
at main.TestHibernateMain.main(TestHibernateMain.java:22)
Caused by: org.hibernate.exception.ConstraintViolationException: could not delete: [server.hibernate.domain.University#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2710)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2893)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:189)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 9 more
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKE9B72644368E5BBD: PUBLIC.FACULTY FOREIGN KEY(UNIVERSITY_ID) REFERENCES PUBLIC.UNIVERSITY(ID)"; SQL statement:
delete from UNIVERSITY where ID=? and VERSION=? [23503-160]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:398)
at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:415)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:291)
at org.h2.table.Table.fireConstraints(Table.java:861)
at org.h2.table.Table.fireAfterRow(Table.java:878)
at org.h2.command.dml.Delete.update(Delete.java:98)
at org.h2.command.CommandContainer.update(CommandContainer.java:73)
at org.h2.command.Command.executeUpdate(Command.java:219)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:143)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:129)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2692)
... 20 more
Can anyone suggest a solution?
Thanks!
I solved my problem by myself.
It is a fetch problem.
When I try remove University by using sessionFactory.delete(university), this university does not fetch any faculties. So the removal will not be cascade enabled.
This because you are trying to delete the UNIVERSITY which is associated with other faculties
thus you have to first delete associated faculties before deleting the university.
I have been programming on a JavaFx application Whiich uses 2 model classes:
package model;
import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class Person implements Serializable{
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},
fetch=FetchType.EAGER, mappedBy="Person")
private ArrayList<Produkt> products= new ArrayList<Produkt>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String email;
private String firstName;
private String lastName;
private String tel;
private String kleurCode;
private String facebook;
public Person() {
super();
}
public Person(String firstName, String lastName, String email,String tel, String facebook, String kleurCode) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
setFacebook(facebook);
setTel(tel);
setKleurCode(kleurCode);
}
public ArrayList<Produkt> getProducts() {
return products;
}
public void setProducts(ArrayList<Produkt> products) {
this.products = products;
}
public void setFacebook(String tel)
{
this.facebook=tel;
}
public String getFacebook() {
return facebook;
}
public void setKleurCode(String tel)
{
this.kleurCode=tel;
}
public String getKleurCode() {
return kleurCode;
}
public String getTel()
{
return tel;
}
public void setTel(String tel)
{
this.tel=tel;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String fName) {
firstName=fName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String fName) {
lastName=fName;
}
public String getPrimary() {
return getEmail();
}
public String getSecondary() {
return getEmail();
}
public String getEmail() {
return email;
}
public void setEmail(String fName) {
email=fName;
}
}
package model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
#Entity
public class Produkt implements Serializable {
String naam;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE},
fetch=FetchType.EAGER)
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Produkt() {
super();
}
public Produkt(Person p, String naam){
p=p;
naam=naam;
};
public String getNaam() {
return naam;
}
public void setNaam(String naam) {
this.naam = naam;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Then i have this Facade class:
package facade;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import model.Person;
import model.Produkt;
public class Facade {
#PersistenceContext(unitName = "EJBModuleDAPU")
private EntityManager em;
public Facade()
{
em=getEntityManager();
}
public void createPerson(Person p) {
if(em!=null){
em.persist(p);
}
else
{
System.out.println("EM was null");
}
}
public void createProduct(Produkt p) {
em.persist(p);
}
public void editProduct(Produkt p) {
em.merge(p);
}
public void editPerson(Person p) {
em.merge(p);
}
public void removePerson(Person p) {
em.remove(em.merge(p));
}
public void removeProduct(Produkt p) {
em.remove(em.merge(p));
}
public Person findPerson(Object id) {
return em.find(Person.class, id);
}
public Produkt findProduct(Object id) {
return em.find(Produkt.class, id);
}
public List<Person> findAllPerson() {
Query query = em.createQuery("SELECT m from Person as m");
return query.getResultList();
/*System.out.println(em.toString());
javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Person.class));
return em.createQuery(cq).getResultList();*/
}
public List<Person> findAllProdcut() {
javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Produkt.class));
return em.createQuery(cq).getResultList();
}
protected EntityManager getEntityManager() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("EJBModuleDAPU");
EntityManager ecm = emf.createEntityManager();
return ecm;
}
}
Here is my Persistence unit:
<?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="EJBModuleDAPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/__default</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<validation-mode>NONE</validation-mode>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
The application runs but when i do a lookup() and try to add a person or get all the list:
WORK
javax.ejb.EJBException
file:/Users/Verdonckt/NetBeansProjects/JavaFXApplicationDa/dist/run298548326/JavaFXApplicationDa.jar!/javafxapplicationda/Sample.fxml
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:213)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
at com.sun.proxy.$Proxy199.voegToePerson(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:144)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:174)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:528)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:199)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1486)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:990)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:214)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.javafx.main.Main.launchApp(Main.java:698)
at com.javafx.main.Main.main(Main.java:871)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:744)
Caused by: javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:213)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
at com.sun.proxy.$Proxy199.voegToePerson(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:144)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:174)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:528)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:199)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1486)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:990)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:214)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: java.lang.IllegalArgumentException: Object: model.Person#7e9d562 is not a known entity type.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4169)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:440)
at facade.Facade.createPerson(Facade.java:35)
at Beans.SessionBeanPersoon.voegToePerson(SessionBeanPersoon.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:206)
... 19 more
2013-12-13 00:52:14.538 java[616:507] [JRSAppKitAWT markAppIsDaemon]: Process manager already initialized: can't fully enable headless mode.
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.javafx.main.Main$2.run(Main.java:948)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:241)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:207)
at java.awt.Window.<init>(Window.java:535)
at java.awt.Frame.<init>(Frame.java:420)
at java.awt.Frame.<init>(Frame.java:385)
at javax.swing.SwingUtilities$SharedOwnerFrame.<init>(SwingUtilities.java:1759)
at javax.swing.SwingUtilities.getSharedOwnerFrame(SwingUtilities.java:1834)
at javax.swing.JOptionPane.getRootFrame(JOptionPane.java:1697)
at javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:863)
at javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:667)
at javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:638)
... 19 more
Java Result: 1
Glassfish server log:
WARNING: Cannot drop tables for application EJBModuleDA. The expected DDL file EJBModuleDA_EJBModuleDAPU_dropDDL.jdbc is not available.
WARNING: Cannot create tables for application EJBModuleDA. The expected DDL file EJBModuleDA_EJBModuleDAPU_createDDL.jdbc is not available.
INFO: EJB5181:Portable JNDI names for EJB SessionBeanPersoon: [java:global/EJBModuleDA/SessionBeanPersoon!Beans.SessionRemote, java:global/EJBModuleDA/SessionBeanPersoon!Beans.SessionBeanPersoon]
INFO: EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB SessionBeanPersoon: [Beans.SessionRemote, Beans.SessionRemote#Beans.SessionRemote]
Anybody that know how i can Resolve this?
Resolved. I rebooted system and reinstalled glassfish. Now it works
I'm trying to save a Entity with relationship many to many with extra column but I've received an error
Band.java
package it.entities;
import java.io.Serializable;
import java.util.ArrayList;
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.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the band database table.
*
*/
#Entity
#Table(name="BAND")
#NamedQuery(name="Band.findAll", query="SELECT b FROM Band b")
public class Band implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private int id;
#Column(name="DESCRIZIONE")
private String descrizione;
#Column(name="NOME")
private String nome;
//bi-directional many-to-one association to Audio
#ManyToOne
#JoinColumn(name="AUDIO_ID")
private Audio audio;
//bi-directional many-to-one association to Video
#ManyToOne
#JoinColumn(name="VIDEO_ID")
private Video video;
//bi-directional many-to-one association to Citta
#ManyToOne
#JoinColumn(name="CITTA_ID")
private Citta citta;
#OneToMany(mappedBy="pk.band", fetch = FetchType.LAZY, cascade={CascadeType.ALL})
private List<BandHasMusicista> bandHasMusicista = new ArrayList<BandHasMusicista>();
public Band() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getDescrizione() {
return this.descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Audio getAudio() {
return this.audio;
}
public void setAudio(Audio audio) {
this.audio = audio;
}
public Video getVideo() {
return this.video;
}
public void setVideo(Video video) {
this.video = video;
}
public Citta getCitta() {
return this.citta;
}
public void setCitta(Citta citta) {
this.citta = citta;
}
// #OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.band")
public List<BandHasMusicista> getBandHasMusicista() {
return bandHasMusicista;
}
public void setBandHasMusicista(List<BandHasMusicista> bandHasMusicista) {
this.bandHasMusicista = bandHasMusicista;
}
}
BandHasMusicista.java
package it.entities;
import java.io.Serializable;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;
/**
* The persistent class for the band_has_musicista database table.
*
*/
#Entity
#Table(name="BAND_HAS_MUSICISTA")
#AssociationOverrides({
#AssociationOverride(name = "pk.musicista", joinColumns = #JoinColumn(name = "MUSICISTA_ID")),
#AssociationOverride(name = "pk.band", joinColumns = #JoinColumn(name = "BAND_ID"))})
#NamedQuery(name="BandHasMusicista.findAll", query="SELECT b FROM BandHasMusicista b")
public class BandHasMusicista implements Serializable {
private static final long serialVersionUID = 1L;
private BandHasMusicistaPK pk = new BandHasMusicistaPK();
private Band band;
private Musicista musicista;
private boolean bandAccept;
private boolean musicistaAccept;
public BandHasMusicista() {
}
#EmbeddedId
public BandHasMusicistaPK getPk() {
return pk;
}
public void setPk(BandHasMusicistaPK pk) {
this.pk = pk;
}
#Column(name="BAND_ACCEPT", nullable=false)
public boolean getBandAccept() {
return this.bandAccept;
}
public void setBandAccept(boolean bandAccept) {
this.bandAccept = bandAccept;
}
#Column(name="MUSICISTA_ACCEPT", nullable=false)
public boolean getMusicistaAccept() {
return this.musicistaAccept;
}
public void setMusicistaAccept(boolean musicistaAccept) {
this.musicistaAccept = musicistaAccept;
}
#Transient
// #JoinColumn(name="BAND_ID")
public Band getBand() {
return this.band;
}
public void setBand(Band band) {
this.band = band;
}
#Transient
// #JoinColumn(name="MUSICISTA_ID")
public Musicista getMusicista() {
return this.musicista;
}
public void setMusicista(Musicista musicista) {
this.musicista = musicista;
}
}
BandHasMusicistaPK.java
package it.entities;
import java.io.Serializable;
import javax.persistence.*;
/**
* The primary key class for the band_has_musicista database table.
*
*/
#Embeddable
public class BandHasMusicistaPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
private Band band;
private Musicista musicista;
public BandHasMusicistaPK() {
}
#ManyToOne
// #JoinColumn(name="BAND_ID")
public Band getBand() {
return this.band;
}
public void setBand(Band band) {
this.band = band;
}
#ManyToOne
// #JoinColumn(name="MUSICISTA_ID")
public Musicista getMusicista() {
return this.musicista;
}
public void setMusicista(Musicista musicista) {
this.musicista = musicista;
}
}
Musicista.java
package it.entities;
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.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
/**
* The persistent class for the MUSICISTA database table.
*
*/
#Entity
#Table(name="MUSICISTA")
#NamedQuery(name="Musicista.findAll", query="SELECT m FROM Musicista m")
public class Musicista implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(generator="SharedPrimaryKeyGenerator")
#GenericGenerator(name="SharedPrimaryKeyGenerator", strategy="foreign", parameters = #Parameter(name="property", value="account"))
#Column(name = "ID", unique = true, nullable = false)
private int id;
#Column(name="COGNOME", nullable=false, length=155)
private String cognome;
#Temporal(TemporalType.DATE)
#Column(name="DATA_NASCITA")
private Date dataNascita;
#Column(name="NOME", nullable=false, length=155)
private String nome;
//bi-directional one-to-one association to Account
#OneToOne
#PrimaryKeyJoinColumn
private Account account;
#OneToMany(mappedBy="pk.musicista", fetch = FetchType.LAZY, cascade={CascadeType.ALL})
private List<BandHasMusicista> bandHasMusicista = new ArrayList<BandHasMusicista>();
public Musicista() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getCognome() {
return this.cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public Date getDataNascita() {
return this.dataNascita;
}
public void setDataNascita(Date dataNascita) {
this.dataNascita = dataNascita;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Account getAccount() {
return this.account;
}
public void setAccount(Account account) {
this.account = account;
}
// #OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.musicista")
public List<BandHasMusicista> getBandHasMusicista() {
return bandHasMusicista;
}
public void setBandHasMusicista(List<BandHasMusicista> bandHasMusicista) {
this.bandHasMusicista = bandHasMusicista;
}
}
BandLogic.java
package it.logic;
import it.entities.Band;
import it.entities.BandHasMusicista;
import it.entities.Citta;
import it.entities.Musicista;
import it.interfaces.ServiceBean;
import it.invo.AddBandInVO;
import javax.persistence.EntityManager;
public class BandLogic {
EntityManager em = null;
/**
* Default constructor.
*/
public BandLogic() {
em = ServiceBean.getEm();
}
public boolean addBand(AddBandInVO inVO) {
System.out.println("IN - addBand() INPUT = " + inVO);
Musicista musicista = em.find(Musicista.class, inVO.getAccountId());
Citta citta = em.find(Citta.class, inVO.getCitta());
if(musicista != null){
Band band = new Band();
band.setNome(inVO.getNome());
band.setDescrizione(inVO.getDescrizione());
band.setCitta(citta);
BandHasMusicista bandHasMusicista = new BandHasMusicista();
bandHasMusicista.setBand(band);
bandHasMusicista.setMusicista(musicista);
bandHasMusicista.setBandAccept(true);
bandHasMusicista.setMusicistaAccept(true);
band.getBandHasMusicista().add(bandHasMusicista);
em.persist(band);
em.flush();
em.clear();
}else{
System.out.println("Account is not Musicista");
return false;
}
System.out.println("OUT - addBand()");
return true;
}
}
The stack trace:
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:307)
at it.logic.BandLogic.addBand(BandLogic.java:46)
at it.interfaces.ServiceBean.addBand(ServiceBean.java:184)
at it.test.BandTest.testAddBand(BandTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
... 22 more
Caused by: java.sql.BatchUpdateException: Column 'BAND_ID' cannot be null
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2054)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1467)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 28 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'BAND_ID' cannot be null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2006)
... 31 more
In this code:
if(musicista != null){
Band band = new Band();
band.setNome(inVO.getNome());
band.setDescrizione(inVO.getDescrizione());
band.setCitta(citta);
BandHasMusicista bandHasMusicista = new BandHasMusicista();
bandHasMusicista.setBand(band);
bandHasMusicista.setMusicista(musicista);
bandHasMusicista.setBandAccept(true);
bandHasMusicista.setMusicistaAccept(true);
band.getBandHasMusicista().add(bandHasMusicista);
em.persist(band);
em.flush();
em.clear();
}
you are creating a new Band and then you are trying to add a Musicista to band. The problem is that at the moment you do em.persist(band) the generated SQL is trying to save the Musicista before saving the Band, therefore BAND_ID which is generated automatically is still null. Save the Band as
if(musicista != null){
Band band = new Band();
band.setNome(inVO.getNome());
band.setDescrizione(inVO.getDescrizione());
band.setCitta(citta);
band = em.persist(band);
BandHasMusicista bandHasMusicista = new BandHasMusicista();
bandHasMusicista.setBand(band);
bandHasMusicista.setMusicista(musicista);
bandHasMusicista.setBandAccept(true);
bandHasMusicista.setMusicistaAccept(true);
band.getBandHasMusicista().add(bandHasMusicista);
em.persist(band);
em.flush();
em.clear();
}
should work (I think you can also do simply em.persist(band); also in the first save, but I am not sure).