Highlighted

Sling Model Exporter

Avatar

Avatar

rajareddych

Avatar

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;

}

}

Replies

Highlighted

Avatar

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281
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.

Highlighted

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

14-01-2019

Assigning IDs to JCR content is not conidered best practice - look at rule 7:

DavidsModel - Jackrabbit Wiki

Highlighted

Avatar

Avatar

rajareddych

Avatar

rajareddych

rajareddych

14-01-2019

Could you please explain with my code.

Highlighted

Avatar

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281
Gaurav-Behl
MVP

14-01-2019

Check this -

synchronization - How to synchronize or lock upon variables in Java? - Stack Overflow

multithreading - How to synchronize a static variable among threads running different instances of a...

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.

Highlighted

Avatar

Avatar

rajareddych

Avatar

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());

}

}

Highlighted

Avatar

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281
Gaurav-Behl
MVP

17-01-2019

let's connect offline as I need more details on your use case.

Highlighted

Avatar

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281

Avatar

Gaurav-Behl

MVP

Total Posts

1.1K

Likes

226

Correct Answer

281
Gaurav-Behl
MVP

17-01-2019

Does this code throw any error? What are you trying to achieve?