Using the following in a custom authenticator in Confluence 3.5/4.0:
com.atlassian.crowd.embedded.api.User crowdUser = crowdService.getUser(user.getName()); ImmutableUser.Builder userBuilder = new ImmutableUser.Builder(); // clone the user before making mods userBuilder.active(crowdUser.isActive()); userBuilder.directoryId(crowdUser.getDirectoryId()); userBuilder.displayName(crowdUser.getDisplayName()); userBuilder.emailAddress(crowdUser.getEmailAddress()); userBuilder.name(crowdUser.getName()); // ... only do the following if name/email is different crowdService.updateUser(userBuilder.toUser());
in one customer environment sometimes produces the following error. Any ideas as to what might be wrong that we could relay to this customer, or is this a problem with our implementation?:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER): Turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition. at org.springframework.orm.hibernate.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1000) at org.springframework.orm.hibernate.HibernateTemplate$11.doInHibernate(HibernateTemplate.java:590) at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:370) at org.springframework.orm.hibernate.HibernateTemplate.update(HibernateTemplate.java:588) at org.springframework.orm.hibernate.HibernateTemplate.update(HibernateTemplate.java:584) at com.atlassian.crowd.embedded.hibernate2.HibernateUserDao.update(HibernateUserDao.java:225) at com.atlassian.confluence.user.crowd.CachedCrowdUserDao.update(CachedCrowdUserDao.java:177) at com.atlassian.crowd.directory.AbstractInternalDirectory.updateUser(AbstractInternalDirectory.java:396) at com.atlassian.crowd.manager.directory.DirectoryManagerGeneric.updateUser(DirectoryManagerGeneric.java:352) at com.atlassian.crowd.manager.application.ApplicationServiceGeneric.updateUser(ApplicationServiceGeneric.java:434) at com.atlassian.crowd.embedded.core.CrowdServiceImpl.updateUser(CrowdServiceImpl.java:315)
Note: I created a ticket for this: CWD-2733
Community moderators have prevented the ability to post new answers.
Hey Gary... Just letting you know I've just encountered this problem, too, while writing a custom authenticator of my own. My initial thought is that the authenticator code that interacts with Embedded Crowd needs to be wrapped in a read/write transaction in order to update the crowd tables successfully.
I'm chasing this up now and will update my answer when I have some answers of my own :)
EDIT: Update
Yes, my initial suspicions were correct. You need to wrap any code that causes updates to the database in a new transaction template. An example of how to do this is here: https://developer.atlassian.com/display/CONFDEV/Hibernate+Sessions+and+Transaction+Management+Guidelines (see the section on 'Manual Transaction Management')
Joe,
Do I need to do that in plugins, too, or just authenticators? For example, we add groups, users, etc. in the Custom Space User Management (CSUM) plugin using embedded Crowd, etc. I totally appreciate the documentation and example code. However, I've put in a bug, because I really don't think this is a good idea. It just doesn't seem very "Atlassian" to require this much code just to do a user update, and it would be great to see a patch we could have users apply. But, there is probably a perfectly sound argument for why things are now so complicated, and I'd like to hear it if it can't be fixed:
https://jira.atlassian.com/browse/CWD-2745
Thanks!
Gary
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Authenticators are a special case, since they are custom code that lives outside the plugin framework. Lots of the bells and whistles that make plugin development easy (automatic dependency injection, transaction management, etc.) just aren't available for authenticators, which leads to a lot of hand-rolled plumbing code to accomplish the same thing.
As far as I know (and sadly I am no guru when it comes to Confluence's transaction management architecture), you may need to do the same transaction-wrapping code in your CSUM plugin (although as you can see in the doco, transaction management in plugins uses a SAL API that is is slightly less lines of code).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Is this true for Jira?
I'm trying to port the confluence authenticator to Jira 5.x and running into problems fetching the transactionManager. This works in the confluence authentator but not in the jira authenticator.
(PlatformTransactionManager) ContainerManager.getComponent("transactionManager");
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
In JIRA, I think you need to use ComponentAccessor, instead of ContainerManager
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Try getComponent(PlatformTransactionManager.class) or getOSGiComponentInstanceOfType(PlatformTransactionManager.class)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.