package com.vladmihalcea.book.hpjp.hibernate.flushing.order;

import com.vladmihalcea.book.hpjp.util.AbstractTest;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.junit.Ignore;
import org.junit.Test;

import javax.persistence.*;

/**
 * @author Vlad Mihalcea
 */
public class FlushOrderTest extends AbstractTest {

    @Override
    protected Class<?>[] entities() {
        return new Class<?>[] {
            Post.class
        };
    }

    @Override
    public void init() {
        super.init();
        doInJPA(entityManager -> {
            Post post = new Post();
            post.setId(1L);
            post.setTitle("High-Performance Java Persistence");
            post.setSlug("high-performance-java-persistence");

            entityManager.persist(post);
        });
    }

    @Test
    @Ignore
    public void testOperationOrder() {
        doInJPA(entityManager -> {
            Post post = entityManager.find(Post.class, 1L);
            entityManager.remove(post);

            Post newPost = new Post();
            newPost.setId(2L);
            newPost.setTitle("High-Performance Java Persistence Book");
            newPost.setSlug("high-performance-java-persistence");
            entityManager.persist(newPost);
        });
    }

    @Test
    public void testOperationOrderWithManualFlush() {
        doInJPA(entityManager -> {
            Post post = entityManager.find(Post.class, 1L);
            entityManager.remove(post);

            entityManager.flush();

            Post newPost = new Post();
            newPost.setId(2L);
            newPost.setTitle("High-Performance Java Persistence Book");
            newPost.setSlug("high-performance-java-persistence");
            entityManager.persist(newPost);
        });
    }

    @Test
    public void testUpdate() {
        doInJPA(entityManager -> {
            Post post = entityManager.unwrap(Session.class)
            .bySimpleNaturalId(Post.class)
            .load("high-performance-java-persistence");

            post.setTitle("High-Performance Java Persistence Book");
        });
    }

    @Entity(name = "Post")
    @Table(
        name = "post",
        uniqueConstraints = @UniqueConstraint(
            name = "slug_uq",
            columnNames = "slug"
        )
    )
    public static class Post {

        @Id
        private Long id;

        private String title;

        @NaturalId
        private String slug;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getSlug() {
            return slug;
        }

        public void setSlug(String slug) {
            this.slug = slug;
        }
    }
}

@@ -197,72 +197,301 @@
 org.
-junit.Ignore;%0Aimport org.junit.Test;%0A%0Aimport javax.persistence.*
+hibernate.engine.spi.EntityEntry;%0Aimport org.hibernate.engine.spi.SharedSessionContractImplementor;%0Aimport org.junit.Ignore;%0Aimport org.junit.Test;%0A%0Aimport javax.persistence.*;%0A%0Aimport java.util.Arrays;%0A%0Aimport static org.junit.Assert.assertEquals;%0Aimport static org.junit.Assert.assertNotNull
 ;%0A%0A/
@@ -733,38 +733,21 @@
 oid 
-init() %7B%0A        super.i
+afterI
 nit()
-;
+ %7B
 %0A   
@@ -2310,25 +2310,681 @@
 Book%22);%0A
-        %7D
+%0A            org.hibernate.engine.spi.PersistenceContext persistenceContext = getHibernatePersistenceContext(%0A                entityManager%0A            );%0A%0A            EntityEntry entityEntry = persistenceContext.getEntry(post);%0A            Object%5B%5D loadedState = entityEntry.getLoadedState();%0A            assertNotNull(loadedState);%0A        %7D);%0A    %7D%0A%0A    private org.hibernate.engine.spi.PersistenceContext getHibernatePersistenceContext(%0A        EntityManager entityManager%0A    ) %7B%0A        SharedSessionContractImplementor session = entityManager.unwrap(%0A            SharedSessionContractImplementor.class%0A        );%0A        return session.getPersistenceContext(
 );%0A    %7D

Update test case to include the First-Level Cache example