Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-17972

PageManager getById can return a Page.class for a blogpost or other non-page

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Medium
    • 4.0
    • None
    • None

    Description

      As mentioned in CONF-16393, CONF-16735 and CONF-16694, calling the getById method on the PageManager with the id of a blog, or any other contententity object, will always return a Page object. The returned Page is horribly broken and can end up in the cache.

      Since PageManager implements ContentEntityManager, and getById returns a ContentEntityObject, this it is not reasonable to assume that getById will only get called with a pageId. There is an expectation that if there is no matching page, then null will be returned. It can be extremely confusing to debug this problem when a PageManager is passed into some other method as a ContentEntityManager.

      It is also quite inobvious how this bug occurs, so I'll explain it.
      The getById method is implemented in only the super class, DefaultContentEntityManager. It is implemented like this:

          public ContentEntityObject getById(long id)
          {
              return contentEntityObjectDao.getById(id);
          }
      

      The weirdness comes down to what contentEntityObjectDao is, and that depends on the applicationContext.xml. In the case of a PageManager the contentEntityObjectDao is currently a PageDao, which returns Page.class from getPersistentClass.

      This gets passed into this method in our HibernateObjectDao

          protected EntityObject getByClassId(final long id)
          {
              EntityObject obj = (EntityObject) getHibernateTemplate().execute(new HibernateCallback()
              {
                  public Object doInHibernate(Session session) throws HibernateException
                  {
                      return session.get(getPersistentClass(), new Long(id));
                  }
              });
      
              return obj;
          }
      

      The javadoc for session.get might lead you to think this would only return pages:

      • Return the persistent instance of the given entity class with the given identifier,
      • or null if there is no such persistent instance. (If the instance, or a proxy for the
      • instance, is already associated with the session, return that instance or proxy.)

      But it doesn't do that until Hibernate 3.2.1. See http://opensource.atlassian.com/projects/hibernate/browse/HHH-1460 and http://opensource.atlassian.com/projects/hibernate/browse/HHH-416.

      Attachments

        Issue Links

          Activity

            People

              don.willis@atlassian.com Don Willis
              don.willis@atlassian.com Don Willis
              Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: