Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 0.9, 1.0
    • Fix Version/s: None
    • Component/s: nodetype
    • Labels:
      None

      Description

      There is currently no way to modify or remove registered node types. The existing reregister and unregister methods in NodeTypeRegistry throw "not yet implemented" exceptions for anything else than trivial node type changes.

      JSR 283 is working on an node type management API that we should ultimately implement.

      1. nodetyperegistry.patch
        10 kB
        Anton Slutsky
      2. OKMSystemSession.java
        5 kB
        Paco Avila

        Issue Links

          Activity

          Hide
          Paco Avila added a comment -

          Any work in the JSR 283 node type management API can deal with this ancient issue?

          Show
          Paco Avila added a comment - Any work in the JSR 283 node type management API can deal with this ancient issue?
          Hide
          Alfie Kirkpatrick added a comment -

          I hacked the Jackrabbit code to always allow node type modifications, regardless of the changes. This had the effect that after introducing a new required property or child node, existing nodes could be loaded but couldn't be saved without fixing the problem. This had the desired effect for me – leave the application to deal with any migration that needs to be done when introducing changes. There is a problem restoring versioned nodes since there is an implicit session save in the restore operation, and therefore no opportunity to fix up a restored node to make it valid. Perhaps restore could be a two stage process, restore into the session and then save.

          Show
          Alfie Kirkpatrick added a comment - I hacked the Jackrabbit code to always allow node type modifications, regardless of the changes. This had the effect that after introducing a new required property or child node, existing nodes could be loaded but couldn't be saved without fixing the problem. This had the desired effect for me – leave the application to deal with any migration that needs to be done when introducing changes. There is a problem restoring versioned nodes since there is an implicit session save in the restore operation, and therefore no opportunity to fix up a restored node to make it valid. Perhaps restore could be a two stage process, restore into the session and then save.
          Hide
          Paco Avila added a comment -

          Is anybody working on this issue?

          Show
          Paco Avila added a comment - Is anybody working on this issue?
          Hide
          Jukka Zitting added a comment -

          We don't seem to have a good consensus on how to resolve this. I suggest to take the discussion back to the mailing list and come back here when we have another patch that addresses the raised concerns.

          See http://thread.gmane.org/gmane.comp.apache.jackrabbit.devel/10643

          Show
          Jukka Zitting added a comment - We don't seem to have a good consensus on how to resolve this. I suggest to take the discussion back to the mailing list and come back here when we have another patch that addresses the raised concerns. See http://thread.gmane.org/gmane.comp.apache.jackrabbit.devel/10643
          Hide
          Anton Slutsky added a comment -

          So has this issue been fixed and I just didnt notice? Or did I say something stupid?

          Show
          Anton Slutsky added a comment - So has this issue been fixed and I just didnt notice? Or did I say something stupid?
          Hide
          Anton Slutsky added a comment -

          Soooo. Any thoughts? Anybody?

          Show
          Anton Slutsky added a comment - Soooo. Any thoughts? Anybody?
          Hide
          Anton Slutsky added a comment -

          I'm thinking, there are basically two alternatives here. Either we expose the SystemSession somehow or we bite the bullet and recurse on each workspace checking for the node type. It could be documented in unregister() that the operation does a slow check and may take time.

          There is another concern however. A mechanism has to be developed to figure out which repository user should be allowed to delete node types. From what I can see, it looks like any session can call unregister() on a node type. It could be a problem. Even if no content exist for a given node type (which would have to be true to be able to unregister()), node types themselves are important. In our application, we have custom node type definitions defining a node structure expected by various JSP templates. Removing a type, even if no content has yet been created, is a big deal.

          Show
          Anton Slutsky added a comment - I'm thinking, there are basically two alternatives here. Either we expose the SystemSession somehow or we bite the bullet and recurse on each workspace checking for the node type. It could be documented in unregister() that the operation does a slow check and may take time. There is another concern however. A mechanism has to be developed to figure out which repository user should be allowed to delete node types. From what I can see, it looks like any session can call unregister() on a node type. It could be a problem. Even if no content exist for a given node type (which would have to be true to be able to unregister()), node types themselves are important. In our application, we have custom node type definitions defining a node structure expected by various JSP templates. Removing a type, even if no content has yet been created, is a big deal.
          Hide
          Anton Slutsky added a comment -

          Thinking about the last comment some more, it probably wont work. It'll work in theory, but it'll be rather hard to ensure backward compantibility

          Show
          Anton Slutsky added a comment - Thinking about the last comment some more, it probably wont work. It'll work in theory, but it'll be rather hard to ensure backward compantibility
          Hide
          Anton Slutsky added a comment -

          We could approach it from the other end. We could create some sort of a persistent meta data repository which could hold dependency information and be updated as a part of a persist transaction. This solution, while being a little bit more involved, will eliminate the need to expose the system session. On the other hand, persisting more stuff during the save operation will obviously be a performance hit.

          Show
          Anton Slutsky added a comment - We could approach it from the other end. We could create some sort of a persistent meta data repository which could hold dependency information and be updated as a part of a persist transaction. This solution, while being a little bit more involved, will eliminate the need to expose the system session. On the other hand, persisting more stuff during the save operation will obviously be a performance hit.
          Hide
          Stefan Guggisberg added a comment -

          > Anton Slutsky commented on JCR-322:
          > -----------------------------------
          >
          > Like I said, extending SessionImpl in the nodetype package is an option. The issue here is not my inability to extend a class and copy code from the org/apache/jackrabbit/core/SystemSession.java file. Its the silliness of such an approach. Basically, what will happen is, we'll be duplicating the SystemSession code just for the sake of duplicating it. I dont believe this is a good thing at all.

          i absolutely agree with anton. publicly exposing the system session on the other hand would be an unacceptable security risk.

          currently there's one internal system session per workspace. sharing this system session might cause other potential issues like e.g. concurrency (since java.jcr.Session is per definition not threadsafe).

          we have to come up with some way of strictly-internally-only exposing a System Session factory. this would btw also require to rewrite some of the workspace housekeeping code (idle workspaces, i.e. those with no logged in sessions, are automatically shutdown) since it would be more difficult to determine whether a workspace is idle or not.

          Show
          Stefan Guggisberg added a comment - > Anton Slutsky commented on JCR-322 : > ----------------------------------- > > Like I said, extending SessionImpl in the nodetype package is an option. The issue here is not my inability to extend a class and copy code from the org/apache/jackrabbit/core/SystemSession.java file. Its the silliness of such an approach. Basically, what will happen is, we'll be duplicating the SystemSession code just for the sake of duplicating it. I dont believe this is a good thing at all. i absolutely agree with anton. publicly exposing the system session on the other hand would be an unacceptable security risk. currently there's one internal system session per workspace. sharing this system session might cause other potential issues like e.g. concurrency (since java.jcr.Session is per definition not threadsafe). we have to come up with some way of strictly-internally-only exposing a System Session factory. this would btw also require to rewrite some of the workspace housekeeping code (idle workspaces, i.e. those with no logged in sessions, are automatically shutdown) since it would be more difficult to determine whether a workspace is idle or not.
          Hide
          Jukka Zitting added a comment -

          It would be very nice if we could make this work below the Session level, i.e. by directly accessing the ItemStateManagers of each workspace. As of now this is not a viable option performance-wise (i.e. no search), but perhaps we could modify things somehow to provide a fast-track access path for the node type reference checks.

          Show
          Jukka Zitting added a comment - It would be very nice if we could make this work below the Session level, i.e. by directly accessing the ItemStateManagers of each workspace. As of now this is not a viable option performance-wise (i.e. no search), but perhaps we could modify things somehow to provide a fast-track access path for the node type reference checks.
          Hide
          Anton Slutsky added a comment -

          Like I said, extending SessionImpl in the nodetype package is an option. The issue here is not my inability to extend a class and copy code from the org/apache/jackrabbit/core/SystemSession.java file. Its the silliness of such an approach. Basically, what will happen is, we'll be duplicating the SystemSession code just for the sake of duplicating it. I dont believe this is a good thing at all.

          Show
          Anton Slutsky added a comment - Like I said, extending SessionImpl in the nodetype package is an option. The issue here is not my inability to extend a class and copy code from the org/apache/jackrabbit/core/SystemSession.java file. Its the silliness of such an approach. Basically, what will happen is, we'll be duplicating the SystemSession code just for the sake of duplicating it. I dont believe this is a good thing at all.
          Hide
          Paco Avila added a comment -

          In this code you can see how I implemented my own SystemSession.

          Show
          Paco Avila added a comment - In this code you can see how I implemented my own SystemSession.
          Hide
          Anton Slutsky added a comment -

          All good points, Stefan. I'll address them.

          The only problem I'm having is, if we are not to expose a getSystemSession() on RepositoryImpl, a slight complication arises. SystemSession class is package private. SessionImpl constructors are protected and I cant use SessionImpl anyway because I need to be able to get around the access manager. The only way I see of getting a low level session to check for things in workspaces is to subclass SessionImpl in org.apache.jackrabbit.core.notetype package and use this new class as my session implementation to get around protection levels. But thats just silly! Something's gotta give. My suggestion here would be to add a SessionManager interface, which could be used to create various types of sessions. But again, thats just a though. If you guys know of a better way, do let me know.

          Show
          Anton Slutsky added a comment - All good points, Stefan. I'll address them. The only problem I'm having is, if we are not to expose a getSystemSession() on RepositoryImpl, a slight complication arises. SystemSession class is package private. SessionImpl constructors are protected and I cant use SessionImpl anyway because I need to be able to get around the access manager. The only way I see of getting a low level session to check for things in workspaces is to subclass SessionImpl in org.apache.jackrabbit.core.notetype package and use this new class as my session implementation to get around protection levels. But thats just silly! Something's gotta give. My suggestion here would be to add a SessionManager interface, which could be used to create various types of sessions. But again, thats just a though. If you guys know of a better way, do let me know.
          Hide
          Stefan Guggisberg added a comment -

          anton, thanks for the patch and your efforts, very much appreciated!

          my main concerns wrt your patch are:

          1. concurrency: i don't agree with your analysis. not all perrsistence operations are invoked through Item.save(). workspace operations e.g. don't call Item.save(). furthermore, sync'ing Item.save() on the Repository instance is not an option since this would severely impact concurrency through heavy nmonitor contention. what we'd really need to do is apply deep locks on root nodes in every workspace or alternatively put repository in 'exclusive' or 'single-user' mode, as mentioned in javadoc.

          2. exposing RepositoryImpl.getSystemSession() is, for obvious reasons, not an option.

          3. you removed the call to getDependentNodeTypes(). note that inter-node type dependencies are not limited to node type inheritance. see http://jackrabbit.apache.org/api-1/org/apache/jackrabbit/core/nodetype/NodeTypeDef.html#getDependencies() for an explanation.

          cheers
          stefan

          Show
          Stefan Guggisberg added a comment - anton, thanks for the patch and your efforts, very much appreciated! my main concerns wrt your patch are: 1. concurrency: i don't agree with your analysis. not all perrsistence operations are invoked through Item.save(). workspace operations e.g. don't call Item.save(). furthermore, sync'ing Item.save() on the Repository instance is not an option since this would severely impact concurrency through heavy nmonitor contention. what we'd really need to do is apply deep locks on root nodes in every workspace or alternatively put repository in 'exclusive' or 'single-user' mode, as mentioned in javadoc. 2. exposing RepositoryImpl.getSystemSession() is, for obvious reasons, not an option. 3. you removed the call to getDependentNodeTypes(). note that inter-node type dependencies are not limited to node type inheritance. see http://jackrabbit.apache.org/api-1/org/apache/jackrabbit/core/nodetype/NodeTypeDef.html#getDependencies( ) for an explanation. cheers stefan
          Hide
          Anton Slutsky added a comment -

          After a lengthy discussion here: http://www.nabble.com/NodeTypeRegistry.checkForReferencesInContent%28%29-tf2882955.html
          (tried to move the thread to the developer forum, but got rejected for some reason), attached is a proposed implementation.

          What this does is, it takes a fairly simplistic "fail-fast" approach. checkForReferencesInContent() executes a query on each workspace searching for nodes of a given type. If any are found, it doesnt try to fix the type, but rather throws a RepositoryException, forcing the caller to deal with its own data issues.

          There are two major issues with this implementation (see thread)
          1. Searching is done by utilizing a query manager, which in turn uses indexes that are outside the physical node storage. This could be a problem, but currently nothing else will scale.

          2. Concurrency. There are four concurrency related use cases that I can forsee at this point.
          a. Not REALLY a concurrency issue, but needs to be addressed. Node is added by a call to addNode(), type is deleted, session is saved by a call to ItemImpl.save() (it looks like everything calls ItemImpl.save() in the end of the day).
          In this case, I dont think much care needs to be taken. All that will happen is, a NoSuchNodeTypeFound exception will be thrown. Which, I think, is fine.

          b. Node type is deleted, new node of type we just deleted is added, session is saved.
          Same as above. Also not a real concurrency issue, but has to be brough up. Let it throw

          c. Now here is the interesting case. While checkForReferenciesInContent() is running, a node of the given type is being persisted by a call to save().
          I saw a lot of discussion on the subject, so I'm pretty sure I'm missing something here, but it seems to me that since we know that no two instances of the RepositoryImpl class are supposed to operate on any given physical repository (see thread), all we really have to do is synchronized ItemImpl.save() and NodeTypeRegistry.checkForReferencesInContent() on the repository object.

          And that is what the attached patch tries to do . Other then these concerns that I just brought up, one more thing kind of bothers me. In order to check each workspace, I had to get a SystemSession. To do that, I had to expose the RepositoryImpl.getSystemSession() method as public. Do feel free to express your opinions on this.

          Show
          Anton Slutsky added a comment - After a lengthy discussion here: http://www.nabble.com/NodeTypeRegistry.checkForReferencesInContent%28%29-tf2882955.html (tried to move the thread to the developer forum, but got rejected for some reason), attached is a proposed implementation. What this does is, it takes a fairly simplistic "fail-fast" approach. checkForReferencesInContent() executes a query on each workspace searching for nodes of a given type. If any are found, it doesnt try to fix the type, but rather throws a RepositoryException, forcing the caller to deal with its own data issues. There are two major issues with this implementation (see thread) 1. Searching is done by utilizing a query manager, which in turn uses indexes that are outside the physical node storage. This could be a problem, but currently nothing else will scale. 2. Concurrency. There are four concurrency related use cases that I can forsee at this point. a. Not REALLY a concurrency issue, but needs to be addressed. Node is added by a call to addNode(), type is deleted, session is saved by a call to ItemImpl.save() (it looks like everything calls ItemImpl.save() in the end of the day). In this case, I dont think much care needs to be taken. All that will happen is, a NoSuchNodeTypeFound exception will be thrown. Which, I think, is fine. b. Node type is deleted, new node of type we just deleted is added, session is saved. Same as above. Also not a real concurrency issue, but has to be brough up. Let it throw c. Now here is the interesting case. While checkForReferenciesInContent() is running, a node of the given type is being persisted by a call to save(). I saw a lot of discussion on the subject, so I'm pretty sure I'm missing something here, but it seems to me that since we know that no two instances of the RepositoryImpl class are supposed to operate on any given physical repository (see thread), all we really have to do is synchronized ItemImpl.save() and NodeTypeRegistry.checkForReferencesInContent() on the repository object. And that is what the attached patch tries to do . Other then these concerns that I just brought up, one more thing kind of bothers me. In order to check each workspace, I had to get a SystemSession. To do that, I had to expose the RepositoryImpl.getSystemSession() method as public. Do feel free to express your opinions on this.
          Hide
          Sandro Boehme added a comment -

          o node type lock:
          >apart from being very difficult/messy to implement with the current architecture
          >this would probably cause a serious and thus inacceptable performance degredation.
          Too bad. I thought this would be a way to go to avoid locking the whole repository.

          o default node type (nt:base // nt:unstructured)
          Of course you are right. I should have had a deeper look in the spec to find it
          out by myself before asking. It's a pity, that it doesn't work. Much thanks for your
          feedback anyway!

          Regards,

          Sandro

          Show
          Sandro Boehme added a comment - o node type lock: >apart from being very difficult/messy to implement with the current architecture >this would probably cause a serious and thus inacceptable performance degredation. Too bad. I thought this would be a way to go to avoid locking the whole repository. o default node type (nt:base // nt:unstructured) Of course you are right. I should have had a deeper look in the spec to find it out by myself before asking. It's a pity, that it doesn't work. Much thanks for your feedback anyway! Regards, Sandro
          Hide
          Stefan Guggisberg added a comment -

          > Sandro Boehme commented on JCR-322:
          > -----------------------------------
          >
          > >e.g. nodes of a specific type
          > >could have been already created transiently but not yet saved, such nodes
          > >could be in the transaction changelog, but not yet committed etc.
          > If I do understand you right, this is some kind of a "lost update problem"
          > because the transaction can use the node type with the commit after we
          > unregistered/changed it.
          > This means we should probably place a lock on the node type before unregistering or
          > changing it and unlock it afterwards. The result of placing a lock on a node type would
          > be that it cannot be used anymore and you get the lock token as soon as every use
          > or transaction using this node type is finished.
          > Even though it's practically not easy to implement, do you think that could
          > theoretically work?

          apart from being very difficult/messy to implement with the current architecture
          this would probably cause a serious and thus inacceptable performance degredation.

          > >just changing the type
          > >of such nodes doesn't work since child items depend on their defining node type
          > >as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing
          > >the node type is guaranteed to affect repository data integrity.
          > You are right all dependent types (subtypes, childtypes) would also need to be
          > changed to nt:base in this case.

          i guess you got me wrong. i wasn't refering to the type hierarchy but to the content
          hierarchy, i.e. child nodes and properties of a node whose node type (or a supertype
          thereof) is about to be replaced. since a child node is defined within its parent node's
          node type this definition would need to be changed as well.

          note that changing a node's node type to "nt:base" would in most cases lead to an illegal
          content structure since "nt:base" doesn't allow any child nodes and properties (except
          jcr:primaryType and jcr:mixinTypes of course). even changing to nt:unstructered might
          cause illegal structures since a parent node might not allow nt:unstructered on child nodes.

          Show
          Stefan Guggisberg added a comment - > Sandro Boehme commented on JCR-322 : > ----------------------------------- > > >e.g. nodes of a specific type > >could have been already created transiently but not yet saved, such nodes > >could be in the transaction changelog, but not yet committed etc. > If I do understand you right, this is some kind of a "lost update problem" > because the transaction can use the node type with the commit after we > unregistered/changed it. > This means we should probably place a lock on the node type before unregistering or > changing it and unlock it afterwards. The result of placing a lock on a node type would > be that it cannot be used anymore and you get the lock token as soon as every use > or transaction using this node type is finished. > Even though it's practically not easy to implement, do you think that could > theoretically work? apart from being very difficult/messy to implement with the current architecture this would probably cause a serious and thus inacceptable performance degredation. > >just changing the type > >of such nodes doesn't work since child items depend on their defining node type > >as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing > >the node type is guaranteed to affect repository data integrity. > You are right all dependent types (subtypes, childtypes) would also need to be > changed to nt:base in this case. i guess you got me wrong. i wasn't refering to the type hierarchy but to the content hierarchy, i.e. child nodes and properties of a node whose node type (or a supertype thereof) is about to be replaced. since a child node is defined within its parent node's node type this definition would need to be changed as well. note that changing a node's node type to "nt:base" would in most cases lead to an illegal content structure since "nt:base" doesn't allow any child nodes and properties (except jcr:primaryType and jcr:mixinTypes of course). even changing to nt:unstructered might cause illegal structures since a parent node might not allow nt:unstructered on child nodes.
          Hide
          Sandro Boehme added a comment -

          >e.g. nodes of a specific type
          >could have been already created transiently but not yet saved, such nodes
          >could be in the transaction changelog, but not yet committed etc.
          If I do understand you right, this is some kind of a "lost update problem"
          because the transaction can use the node type with the commit after we
          unregistered/changed it.
          This means we should probably place a lock on the node type before unregistering or
          changing it and unlock it afterwards. The result of placing a lock on a node type would
          be that it cannot be used anymore and you get the lock token as soon as every use
          or transaction using this node type is finished.
          Even though it's practically not easy to implement, do you think that could
          theoretically work?

          >just changing the type
          >of such nodes doesn't work since child items depend on their defining node type
          >as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing
          >the node type is guaranteed to affect repository data integrity.
          You are right all dependent types (subtypes, childtypes) would also need to be
          changed to nt:base in this case.
          The idea behind changing the type is just, that the data does not need to be
          deleted if someone want to change (e.g. restructure) the nodetype. But at the
          moment I think that doesn't make this issue easier to solve.

          >see javadoc (i.e. the TODO comment) of NodeTypeRegistry#checkForReferencesInContent()
          >for more details.
          Thanks for the hint. Here is a link to make it clicky as a reference for this issue:
          http://jackrabbit.apache.org/api-1/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.html#checkForReferencesInContent(org.apache.jackrabbit.name.QName)

          Show
          Sandro Boehme added a comment - >e.g. nodes of a specific type >could have been already created transiently but not yet saved, such nodes >could be in the transaction changelog, but not yet committed etc. If I do understand you right, this is some kind of a "lost update problem" because the transaction can use the node type with the commit after we unregistered/changed it. This means we should probably place a lock on the node type before unregistering or changing it and unlock it afterwards. The result of placing a lock on a node type would be that it cannot be used anymore and you get the lock token as soon as every use or transaction using this node type is finished. Even though it's practically not easy to implement, do you think that could theoretically work? >just changing the type >of such nodes doesn't work since child items depend on their defining node type >as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing >the node type is guaranteed to affect repository data integrity. You are right all dependent types (subtypes, childtypes) would also need to be changed to nt:base in this case. The idea behind changing the type is just, that the data does not need to be deleted if someone want to change (e.g. restructure) the nodetype. But at the moment I think that doesn't make this issue easier to solve. >see javadoc (i.e. the TODO comment) of NodeTypeRegistry#checkForReferencesInContent() >for more details. Thanks for the hint. Here is a link to make it clicky as a reference for this issue: http://jackrabbit.apache.org/api-1/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.html#checkForReferencesInContent(org.apache.jackrabbit.name.QName )
          Hide
          Stefan Guggisberg added a comment -

          > Sandro Boehme commented on JCR-322:
          > -----------------------------------
          >
          > People in the mailling list sometimes say that a deep lock is needed
          > and that this is a big problem in this issue.
          > I guess it is needed to avoid the new creation of nodes after
          > the search for nodes with the node type that has to be unregistered.
          > If that's the case maybe there is a way to avoid the deep lock.
          > If a user tries to add a node with a node type that is currently
          > being unregistered a NodeTypeNotFoundException (or similar) could
          > already be thrown. This way it's possible to search for all nodes with
          > this type and change the type to nt:base while the amount of nodes
          > with this type will not change anymore.

          unfortunately that wouldn't solve the issue at hand.

          first of all, there's no easy and elegant way of temporarily preventing node
          creation of a specific type (or a subtype thereof!). e.g. nodes of a specific type
          could have been already created transiently but not yet saved, such nodes
          could be in the transaction changelog, but not yet committed etc.

          second, the purpose of the NodeTypeRegistry#checkForReferencesInContent()
          method is to reliably determine if there exists any instance of a specific type
          in content. if such exist the type can't be unregistered. just changing the type
          of such nodes doesn't work since child items depend on their defining node type
          as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing
          the node type is guaranteed to affect repository data integrity.

          see javadoc (i.e. the TODO comment) of NodeTypeRegistry#checkForReferencesInContent()
          for more details.

          > To search for nodes by type the following query should work
          > "//element(*, nt:nodeType)". Of course this needs to be done for
          > every workspace.
          > Do you think that could work?

          Show
          Stefan Guggisberg added a comment - > Sandro Boehme commented on JCR-322 : > ----------------------------------- > > People in the mailling list sometimes say that a deep lock is needed > and that this is a big problem in this issue. > I guess it is needed to avoid the new creation of nodes after > the search for nodes with the node type that has to be unregistered. > If that's the case maybe there is a way to avoid the deep lock. > If a user tries to add a node with a node type that is currently > being unregistered a NodeTypeNotFoundException (or similar) could > already be thrown. This way it's possible to search for all nodes with > this type and change the type to nt:base while the amount of nodes > with this type will not change anymore. unfortunately that wouldn't solve the issue at hand. first of all, there's no easy and elegant way of temporarily preventing node creation of a specific type (or a subtype thereof!). e.g. nodes of a specific type could have been already created transiently but not yet saved, such nodes could be in the transaction changelog, but not yet committed etc. second, the purpose of the NodeTypeRegistry#checkForReferencesInContent() method is to reliably determine if there exists any instance of a specific type in content. if such exist the type can't be unregistered. just changing the type of such nodes doesn't work since child items depend on their defining node type as well (-> Property#getDefiniton()#getDeclaringNodeType()). just changing the node type is guaranteed to affect repository data integrity. see javadoc (i.e. the TODO comment) of NodeTypeRegistry#checkForReferencesInContent() for more details. > To search for nodes by type the following query should work > "//element(*, nt:nodeType)". Of course this needs to be done for > every workspace. > Do you think that could work?
          Hide
          Sandro Boehme added a comment -

          People in the mailling list sometimes say that a deep lock is needed
          and that this is a big problem in this issue.
          I guess it is needed to avoid the new creation of nodes after
          the search for nodes with the node type that has to be unregistered.
          If that's the case maybe there is a way to avoid the deep lock.
          If a user tries to add a node with a node type that is currently
          being unregistered a NodeTypeNotFoundException (or similar) could
          already be thrown. This way it's possible to search for all nodes with
          this type and change the type to nt:base while the amount of nodes
          with this type will not change anymore.
          To search for nodes by type the following query should work
          "//element(*, nt:nodeType)". Of course this needs to be done for
          every workspace.
          Do you think that could work?

          Show
          Sandro Boehme added a comment - People in the mailling list sometimes say that a deep lock is needed and that this is a big problem in this issue. I guess it is needed to avoid the new creation of nodes after the search for nodes with the node type that has to be unregistered. If that's the case maybe there is a way to avoid the deep lock. If a user tries to add a node with a node type that is currently being unregistered a NodeTypeNotFoundException (or similar) could already be thrown. This way it's possible to search for all nodes with this type and change the type to nt:base while the amount of nodes with this type will not change anymore. To search for nodes by type the following query should work "//element(*, nt:nodeType)". Of course this needs to be done for every workspace. Do you think that could work?
          Hide
          Stefan Guggisberg added a comment -

          trivial node type modifications (i.e. those that do not affect the consistency of existing content) are supported for quite a while now.
          what's missing is support for non-trivial modifications.

          Show
          Stefan Guggisberg added a comment - trivial node type modifications (i.e. those that do not affect the consistency of existing content) are supported for quite a while now. what's missing is support for non-trivial modifications.

            People

            • Assignee:
              Unassigned
              Reporter:
              Jukka Zitting
            • Votes:
              8 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:

                Development