title: LoadableDetachableModel multi-threading issue
body: <p>We had an issue where a lot of users were hitting a page that had a lot of ajax calls on it. It took us a long time to run down and we finally found a threading issue in LoadableDetachableModel.</p>
  
  <p>I think the problem is related to the fact that we have a UserModel in the Session. This UserModel extends LoadableDetachableModel. If the load() method takes too long to return then a second Thread could get a null User returned based on the fact that the attached flag is set to true before load() is called and before transientModelObject is set. To fix it we simply made our own modified version of LoadableDetachableModel that added synchronization where necessary. Since then we have had no more problems. </p>
  
  <p>I looked around in the Wicket Jira site and even looked at some commits within fisheye to see if this issue had been fixed because I noticed Wicket 7 does not have an attached flag. Instead it has an enum called InternalState to fix WICKET-5916. It appears the threading issue is still present in the 7.2 version of wicket. Here is the code:</p>
  
  <pre><code>    @Override
  public final T getObject()
  {
      if (state == null || state == InternalState.DETACHED)
      {
          // prevent infinite attachment loops
          state = InternalState.ATTACHING;//&lt;--One thread sets this, next thread gets a null object returned since load() has not completed
  
          transientModelObject = load();
  
          if (log.isDebugEnabled())
          {
              log.debug("loaded transient object " + transientModelObject + " for " + this +
                  ", requestCycle " + RequestCycle.get());
          }
  
          state = InternalState.ATTACHED;
          onAttach();
      }
      return transientModelObject;
  }
  </code></pre>
  
  <p>As you can see, if a single thread calls getObject() and gets to the line calling load() then the model has the state variable set to ATTACHING. Now, the next thread calls getObject() before the load() completes and gets a null object returned since state is not null and state is not DETACHED. </p>
  
  <p>Again, I think this could only happen if you are using a LoadableDetachableModel in your Session or Application class where multiple threads could reuse the same model.</p>
  
  <p>Am I missing something or should I file a bug report? Should I not be using a LoadableDetachableModel in the Session?</p>