I want to migrate an existing single-tenant application to multi-tenant application.
The first step is to create a default tenant and get it connect to the application, the code is as following:
the model :
@Entity
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
@Table(name = "UTILISATEUR")
public class User implements Serializable {
@SequenceGenerator(name = "USER_SEQ", sequenceName = "user_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
private String username;
private String password;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = {
@JoinColumn(name = "User_userid")}, inverseJoinColumns = {
@JoinColumn(name = "Role_roleid")})
private List<Role> roles;
..... }
@Entity
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
public class Role implements Serializable {
@Id
@SequenceGenerator(name = "ROLE_SEQ", sequenceName = "ROLE_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ROLE_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
private String
private String rolename;
@ManyToMany(mappedBy = "roles")
private List<User> users;
public Integer getId() {
return id;
}
....}
the persistence.xml file:
<?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="com.nz_war_1.0-SNAPSHOTPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/SimpleCRUD_JDBC</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.logging.level" value="fine" />
<property name="eclipselink.tenant-id" value="default_tenant" />
</properties>
</persistence-unit>
</persistence>
I created a Singleton class to have the Entity Manager Factory:
public class EmfProvider {
private static final String DB_PU = "com.nz_war_1.0-SNAPSHOTPU";
public static final boolean DEBUG = true;
private static final EmfProvider singleton = new EmfProvider();
private EntityManagerFactory emf;
private EmfProvider() {
}
public static EmfProvider getInstance() {
return singleton;
}
public EntityManagerFactory getEntityManagerFactory() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory(DB_PU);
}
if (DEBUG) {
System.out.println("factory created on: " + new Date());
}
return emf;
}
public void closeEmf() {
if (emf.isOpen() || emf != null) {
emf.close();
}
emf = null;
if (DEBUG) {
System.out.println("EMF closed at: " + new Date());
}
}
}
The facade: Note that I don't user @persistenceContext, and create the entitymanager using the persistence unit manually because later we have to deterimine the persistenceuUnit to use programaticly:
public abstract class DataAccessService<T> {
private EntityManager em;
public DataAccessService() {}
private Class<T> type;
public DataAccessService(Class<T> type) {
this.type = type;
}
public void create(T t) {
em = EmfProvider.getInstance().getEntityManagerFactory().createEntityManager();
this.em.persist(t);
this.em.flush();
this.em.refresh(t);
public List findWithNamedQuery(String namedQueryName) {
em = EmfProvider.getInstance().getEntityManagerFactory().createEntityManager();
return this.em.createNamedQuery(namedQueryName).getResultList();
}
..........
}
@Stateless
public class UserService extends DataAccessService<User>{
public UserService(){
super(User.class);
}
}
after running the project I get an exception which is: Predeployment of PersistenceUnit [com.nz_war_1.0-SNAPSHOTPU] failed.
and a long error in glassfish log:
Avertissement: EJB5184:A system exception occurred during an invocation on EJB UserService, method: public java.util.List com.nz.simplecrud.service.DataAccessService.findWithNamedQuery(java.lang.String)
Avertissement: 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.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at com.sun.proxy.$Proxy284.findWithNamedQuery(Unknown Source)
at com.nz.simplecrud.service.__EJB31_Generated__UserService__Intf____Bean__.findWithNamedQuery(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 org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:267)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:263)
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:110)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
at com.nz.simplecrud.service.UserService$Proxy$_$$_Weld$Proxy$.findWithNamedQuery(UserService$Proxy$_$$_Weld$Proxy$.java)
at com.nz.simplecrud.controller.UserController.init(UserController.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
......
Caused by: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.nz_war_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.nz.simplecrud.entities.UserRoleView] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:111)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:183)
....
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.nz_war_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.nz.simplecrud.entities.UserRoleView] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:2023)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2014)
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.nz_war_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.nz.simplecrud.entities.UserRoleView] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:231)
... 135 more
Caused by: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.nz.simplecrud.entities.UserRoleView] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.ValidationException.noPrimaryKeyAnnotationsFound(ValidationException.java:1425)
Grave: Error Rendering View[/admin/UserList.xhtml]
javax.el.ELException: /admin/UserList.xhtml @12,69 value="#{userController.lazyModel}": org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public com.nz.simplecrud.controller.UserController.init() on com.nz.simplecrud.controller.UserController@519c628d
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)....
Grave: Error Rendering View[/admin/UserList.xhtml]
javax.el.ELException: /admin/UserList.xhtml @12,69 value="#{userController.lazyModel}": org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public com.nz.simplecrud.controller.UserController.init() on com.nz.simplecrud.controller.UserController@5bcd013b
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIData.getValue(UIData.java:731)....
Caused by: org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public com.nz.simplecrud.controller.UserController.init() on com.nz.simplecrud.controller.UserController@5bcd013b
at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:400)
at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.postConstruct(ManagedBean.java:174)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:294)
at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:107)
Can any one help me please. Thank you.