rajareddych
rajareddych
14-01-2019
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;
}
}
Gaurav-Behl
MVP
Gaurav-Behl
MVP
14-01-2019
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.
smacdonald2008
smacdonald2008
14-01-2019
Assigning IDs to JCR content is not conidered best practice - look at rule 7:
rajareddych
rajareddych
14-01-2019
Could you please explain with my code.
Gaurav-Behl
MVP
Gaurav-Behl
MVP
14-01-2019
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.
rajareddych
rajareddych
17-01-2019
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());
}
}
Gaurav-Behl
MVP
Gaurav-Behl
MVP
17-01-2019
let's connect offline as I need more details on your use case.
Gaurav-Behl
MVP
Gaurav-Behl
MVP
17-01-2019
Does this code throw any error? What are you trying to achieve?