/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed 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
 *
 *      http://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
 * limitations under the License.
*/
package anyframe.core.hibernate.basic;

import org.hibernate.Hibernate;
import org.hibernate.LazyInitializationException;

import anyframe.core.hibernate.AbstractConfigurationalTest;
import anyframe.core.hibernate.SetUpInitData;
import anyframe.sample.model.bidirection.Category;
import anyframe.sample.model.bidirection.Country;
import anyframe.sample.model.bidirection.Movie;

/**
 * TestCase Name :
 * HibernatePersistentObjectStatesTest<br>
 * <br>
 * [Description] : Persistent Object의 state에는 Transient, Persistent, Detached
 * 세개의 상태가 있다. Persistent, Detached 상태일때 Hibernate에서 Persistent Object
 * 를 어떻게 관리하는지 알아본다.<br>
 * [Main Flow]
 * <ul>
 * <li>#-1 Positive Case : persistent state인 Category객체의 값을 바꾼
 * 후 update나 save 메소드의 직접적인 호출 없이 
 * session을 종료 하였을 때 변환 된 객체의 값이 DB에 자동으로 반영된다.</li>
 * <li>#-2 Positive Case :persistent state인 Category객체를 session을 
 * 닫아 detached state로 만들고 Category객체의 값을 변경한 후 
 * update나 save 메소드직접 호출 하지 않고 session을 종료 하였을 때 
 * persistent state일 때와는 다르게 DB에 반영이 되지 않는다.</li>
 * </ul>
 * @author Jonghoon Kim
 */


public class HibernatePersistentObjectStatesTest extends
    AbstractConfigurationalTest {
   
    protected String getHibernateConfigLocation() {
        return "hibernateconfig/hibernate.cfg.xml";
    }
    /**
     * [Flow #-1] Positive Case : persistent state인 Category객체의 값을 바꾼
     * 후 update나 save 메소드의 직접적인 호출 없이 
     * session을 종료 하였을 때 변환 된 객체의 값이 DB에 자동으로 반영된다.
     * 
     * @throws Exception
     *             throws exception which is from hibernate
     */
    public void testPersistentState() throws Exception {
        // 1. start a new session and transaction
        newSession();
        
        // 2. persistent object is transient state
        Category category = new Category();
        category.setCategoryId("CTGR-0001");
        category.setCategoryName("Romantic");
        category.setCategoryDesc("Romantic genre");
        
        // 3. persistent class is persistent state
        session.save(category);
        
        // 4. change value of persistent object
        category.setCategoryName("Comedy");
        category.setCategoryDesc("Comedy consists...");
        
        // 5. close session
        closeSession();
        
        // 6. check persistent state
        newSession();
        Category categoryResult = (Category) session.get(Category.class, "CTGR-0001");
        closeSession();
        assertEquals("Comedy", categoryResult.getCategoryName());
        assertEquals("Comedy consists...", categoryResult.getCategoryDesc());
    }

    /**
     * [Flow #-2] Positive Case : persistent state인 Category객체를 session을 
     * 닫아 detached state로 만들고 Category객체의 값을 변경한 후 
     * update나 save 메소드직접 호출 하지 않고 session을 종료 하였을 때 
     * persistent state일 때와는 다르게 DB에 반영이 되지 않는다.
     * 
     * @throws Exception
     *             throws exception which is from hibernate
     */
    public void testDetachedState() throws Exception {
        // 1. start a new session and transaction
        newSession();
        
        // 2. persistent object is transient state
        Category category = new Category();
        category.setCategoryId("CTGR-0001");
        category.setCategoryName("Romantic");
        category.setCategoryDesc("Romantic genre");
        
        // 3. persistent class is persistent state
        session.save(category);
        
        // 4. close session
        // 5. persistent class is Detached state
        closeSession();
        
        // 6. start a new session and transaction
        newSession();

        // 7. change value of persistent object
        category.setCategoryName("Comedy");
        category.setCategoryDesc("Comedy consists");
        // 8. close session
        closeSession();
        
        // 9. check persistent state
        newSession();
        Category categoryResult = (Category) session.get(Category.class, "CTGR-0001");
        assertNotSame("Comedy", categoryResult.getCategoryName());
        assertNotSame("Comedy consists...", categoryResult.getCategoryDesc());
    }

}

