/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
<<<<<<< Updated upstream
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
=======
 * 
 *     https://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
>>>>>>> Stashed changes
 * limitations under the License.
 */

/*
 * InstanceCallbacks.java
 *
 */

package javax.jdo;

/**
 * A <code>PersistenceCapable</code> class that provides callback methods for life cycle events
 * implements this interface.
 *
 * <p>For JDO 2.0, <code>InstanceCallbacks</code> has been refactored to extend four other
 * interfaces, without changing any of the methods or semantics. This allows fine-grained control
 * over callbacks, for example to allow a class to implement the load callback without implementing
 * any of the other callbacks. For backward compatibility with JDO 1.0, the <code>InstanceCallbacks
 * </code> interface is preserved.
 *
 * <p>Classes which include non-persistent fields whose values depend on the values of persistent
 * fields require callbacks on specific JDO instance life cycle events in order to correctly
 * populate the values in these fields.
 *
 * <p>The callbacks might also be used if the persistent instances need to be put into the runtime
 * infrastructure of the application. For example, a persistent instance might notify other
 * instances on changes to state. The persistent instance might be in a list of managed instances.
 * When the persistent instance is made hollow, it can no longer generate change events, and the
 * persistent instance should be removed from the list of managed instances.
 *
 * <p>To implement this, the application programmer would implement <code>jdoPostLoad</code> to put
 * itself into the list of managed instances, and implement <code>jdoPreClear</code> to remove
 * itself from the list. With JDO 1.0, the domain class would be declared to implement <code>
 * InstanceCallbacks</code>. With JDO 2.0, the domain class would be declared to implement <code>
 * javax.jdo.listener.LoadCallback</code> and <code>javax.jdo.listener.ClearCallback</code>.
 *
 * <p>Note that JDO does not manage the state of non-persistent fields, and when a JDO instance
 * transitions to hollow, JDO clears the persistent fields. It is the programmer's responsibility to
 * clear non-persistent fields so that garbage collection of referred instances can occur.
 *
 * @since 1.0
 * @version 2.0
 */
public interface InstanceCallbacks
    extends javax.jdo.listener.ClearCallback,
        javax.jdo.listener.DeleteCallback,
        javax.jdo.listener.LoadCallback,
        javax.jdo.listener.StoreCallback {}
