I have a sling model exporter to generate IDs for pages created in AEM.
Issue: When I create pages under new folders, duplicate IDs is generated.
Eg: "Folder 1 has page with ID 1234, If page is created under Folder 2, it also has ID 1234"
I want to generate Unique IDs for every page created, irrespective of folder.
Please help me if anything to be changed in my code.
My Code:
public class SequentialNumberImpl implements SequentialNumberService {
private static Logger log = LoggerFactory.getLogger(SequentialNumberImpl.class);
AtomicLong atomicLong = new AtomicLong(999);
@Reference
private SlingRepository slingRepository;
private AtomicLong formID;
@Activate
public void activate(ComponentContext context) //throws LoginException {
{
Session session = null;
long formIdStart = 999;
try {
session = slingRepository.loginService("sequential-number-service", null);
Node idNode = session.getNode(Constants.ID_PATH);
if (idNode.hasProperty(Constants.FORM_ID)) {
formIdStart = idNode.getProperty(Constants.FORM_ID).getLong();
}
formID = new AtomicLong(formIdStart);
log.debug("formID: {}", formID.get());
} catch (RepositoryException re) {
log.error(Constants.ERROR, re);
} finally {
if (session != null && session.isLive()) {
session.logout();
}
}
}
@Deactivate
protected void deactivate(ComponentContext context) {
{
Session sessionDeactivate = null;
try {
sessionDeactivate = slingRepository.loginService("sequential-number-service", null);
Node idNodeDeactivate = sessionDeactivate.getNode(Constants.ID_PATH);
idNodeDeactivate.setProperty(Constants.FORM_ID, formID.get());
idNodeDeactivate.getSession().save();
log.debug("formID: {}", formID.get());
} catch (ValueFormatException vfe) {
log.error(Constants.PROCESSING_ERROR, vfe);
} catch (VersionException ve) {
log.error(Constants.PROCESSING_ERROR, ve);
} catch (LockException le) {
log.error(Constants.PROCESSING_ERROR, le);
} catch (ConstraintViolationException cve) {
log.error(Constants.PROCESSING_ERROR, cve);
} catch (RepositoryException re) {
log.error(Constants.PROCESSING_ERROR, re);
} finally {
if (sessionDeactivate != null && sessionDeactivate.isLive()) {
sessionDeactivate.logout();
}
}
}
@Override
public String generateSequentialNumber(String idName) {
String finalIdValue = null;
log.debug("Entered into generateSequentialNumber{} :");
if (idName.equalsIgnoreCase(Constants.CONTENT_FORM_ID)) {
finalIdValue = Constants.FORM_ID_PREFIX + Long.toString(formID.addAndGet(1));
}
log.debug("Returning finalIdValue from generateSequentialNumber{} : ", finalIdValue);
return finalIdValue;
}
}
Views
Replies
Total Likes
Assuming that the rest of code is working fine, the duplicate Ids are most likely being generated due to concurrency issues.
Move the member variable to synchronized methods/blocks and test.
Views
Replies
Total Likes
Could you please explain with my code.
Views
Replies
Total Likes
Check this -
synchronization - How to synchronize or lock upon variables in Java? - Stack Overflow
Java Synchronization Tutorial : What, How and Why?
move your variable - formId to synchronized block
Last but not least as Scott mentioned about the best practices, just utilize these sequential numbers appropriately.
Views
Replies
Total Likes
I had posted different code. Please let me know the updates I need for the below code.
Here I'm checking for formID to be null or empty, I think, I also need to check for duplicate ID
@PostConstruct
protected void invokePost()
{
Node jcrNode = null;
Node currentNode = resource.adaptTo(Node.class);
PageManager pageManager = resource.getResourceResolver().adaptTo(PageManager.class);
if (pageManager != null)
{
jcrNode = pageManager.getContainingPage(resource).getContentResource().adaptTo(Node.class);
}
try
{
// Checking if form id is null or empty
if ((formId == null || formId.isEmpty()) && jcrNode != null && jcrNode.hasProperty(Constants.SLING_ALIAS) && currentNode != null)
{
// set the formId with the sling:alias property value
currentNode.setProperty(formIdProperty, jcrNode.getProperty(Constants.SLING_ALIAS).getValue().getString());
currentNode.getSession().save();
}
}
catch (RepositoryException e)
{
log.error(Constants.MSG_PROCESSING_ERROR + e.getMessage());
}
}
Views
Replies
Total Likes
let's connect offline as I need more details on your use case.
Views
Replies
Total Likes
Does this code throw any error? What are you trying to achieve?
Views
Replies
Total Likes
Assigning IDs to JCR content is not conidered best practice - look at rule 7:
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies