-
Feature Request
-
Resolution: Done
-
Major
-
PLINK_2.5.0.CR1
-
None
-
None
Good morning guys, looks like we found a issue with custom entities (I already checked the latest updates from PL documentation). When the application is deployed twice and the database updated, looks like SampleModel.getUser can't find the user specified, as consequence some applications may fail.
Let me give an example, try to deploy the following code twice and check if the method SampleModel.getUser will return null.
persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="picketlink-default" transaction-type="JTA"> <description>PicketLink Persistence Unit</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/datasources/DefaultDS</jta-data-source> <class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class> <class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class> <class>org.jboss.aerogear.aerodoc.model.SaleAgent</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.transaction.flush_before_completion" value="true"/> </properties> </persistence-unit> </persistence>
Resources.java
public class Resources { @SuppressWarnings("unused") @PicketLink @PersistenceContext(unitName = "picketlink-default") @Produces private EntityManager picketLinkEntityManager; }
SaleAgent.java
import org.picketlink.idm.model.Attribute; import org.picketlink.idm.model.sample.Agent; import javax.persistence.Entity; import java.io.Serializable; @Entity public class SaleAgent extends User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", updatable = false, nullable = false) private Long id; private String status; private String password; private String location; public void setId(Long id) { this.id = id; } public String getStatus() { return this.getAttribute("status").getValue().toString(); } public void setStatus(final String status) { this.setAttribute(new Attribute("status", status)); } public String getLocation() { return this.getAttribute("location").getValue().toString(); } public void setLocation(final String location) { this.setAttribute(new Attribute("location", location)); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
PicketLinkDefaultUsers.xml
import org.picketlink.idm.IdentityManager; import org.picketlink.idm.PartitionManager; import org.picketlink.idm.RelationshipManager; import org.picketlink.idm.credential.Password; import org.picketlink.idm.model.sample.Agent; import org.picketlink.idm.model.sample.Role; import org.picketlink.idm.model.sample.SampleModel; import org.picketlink.idm.model.sample.User; import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.inject.Inject; @Singleton @Startup public class PicketLinkDefaultUsers { @Inject private PartitionManager partitionManager; private IdentityManager identityManager; private RelationshipManager relationshipManager; @PostConstruct public void create() { this.identityManager = partitionManager.createIdentityManager(); this.relationshipManager = partitionManager.createRelationshipManager(); final String DEFAULT_USER = "john"; User adminUser = SampleModel.getUser(identityManager, DEFAULT_USER); //Will always be null even if it already exists into the database if (adminUser == null) { SaleAgent john = new SaleAgent(); john.setLocation("New York"); john.setStatus("PTO"); john.setLoginName("john"); this.identityManager.add(john); this.identityManager.updateCredential(john, new Password("123")); Role admin = new Role("admin"); this.identityManager.add(admin); Role simple = new Role("simple"); this.identityManager.add(simple); grantRoles(john, admin); grantRoles(john, simple); } } private void grantRoles(Agent agent, Role role) { SampleModel.grantRole(relationshipManager, agent, role); } }
Stacktrace.txt
Caused by: javax.ejb.EJBException: org.picketlink.idm.IdentityManagementException: PLIDM000001: IdentityType [class org.jboss.aerogear.aerodoc.model.SaleAgent] already exists with the given identifier [SaleAgent ] for the given Partition [f4d85765-ed7d-4a23-b5e2-70903544dd05]. at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:166) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:230) at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:333) at org.jboss.as.ejb3.tx.SingletonLifecycleCMTTxInterceptor.processInvocation(SingletonLifecycleCMTTxInterceptor.java:56) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:161) ... 9 more Caused by: org.picketlink.idm.IdentityManagementException: PLIDM000001: IdentityType [class org.jboss.aerogear.aerodoc.model.SaleAgent] already exists with the given identifier [SaleAgent ] for the given Partition [f4d85765-ed7d-4a23-b5e2-70903544dd05]. at org.picketlink.idm.internal.ContextualIdentityManager.checkUniqueness(ContextualIdentityManager.java:233) at org.picketlink.idm.internal.ContextualIdentityManager.add(ContextualIdentityManager.java:84) at org.jboss.aerogear.aerodoc.config.PicketLinkDefaultUsers.create(PicketLinkDefaultUsers.java:85) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_25] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_25] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_25] at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_25] at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptorFactory$ManagedReferenceLifecycleMethodInterceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptorFactory.java:130) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:73) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ee.component.ManagedReferenceInterceptorFactory$ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptorFactory.java:95) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:228) ... 18 more
Let me know if we are doing something wrong, thanks in advance