package lemming.lemma;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lemming.data.EntityManagerListener;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.query.Query;

import javax.annotation.security.RolesAllowed;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.OutputStream;

/**
 * A resource for lemma data.
 */
@Path("lemmas")
@RolesAllowed({"STUDENT","USER","ADMIN"})
public class LemmaResource {
    /**
     * Returns a chunked JSON response.
     *
     * @return A JSON response.
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response get() {
        EntityManager entityManager1 = EntityManagerListener.createEntityManager();
        EntityManager entityManager2 = EntityManagerListener.createEntityManager();
        EntityTransaction transaction = null;

        try {
            StatelessSession session = entityManager1.unwrap(Session.class).getSessionFactory().openStatelessSession();
            final EntityTransaction finalTransaction = session.beginTransaction();
            transaction = finalTransaction;
            Query query = session.createQuery("SELECT l.id FROM Lemma l WHERE l.replacement IS NULL ORDER BY l.name");
            query.setReadOnly(true).setCacheable(false).setFetchSize(Integer.MIN_VALUE);
            ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
            StreamingOutput streamingOutput = new StreamingOutput() {
                @Override
                public void write(OutputStream outputStream) throws IOException, WebApplicationException {
                    JsonGenerator jsonGenerator = new ObjectMapper().configure(MapperFeature.USE_ANNOTATIONS, true)
                            .getFactory().createGenerator(outputStream, JsonEncoding.UTF8);
                    jsonGenerator.writeStartArray();

                    while (results.next()) {
                        Lemma lemma = entityManager2.find(Lemma.class, results.get(0));

                        if (lemma instanceof Lemma) {
                            jsonGenerator.writeObject(lemma);
                        }

                        entityManager2.clear();
                    }

                    jsonGenerator.writeEndArray();
                    jsonGenerator.flush();
                    jsonGenerator.close();
                    entityManager2.close();
                    results.close();
                    finalTransaction.commit();
                }
            };

            return Response.ok(streamingOutput).type(MediaType.APPLICATION_JSON)
                    .header("Content-Disposition", "attachment; filename=\"lemmata.json\"").build();
        } catch (RuntimeException e) {
            e.printStackTrace();

            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }

            throw e;
        } finally {
            entityManager1.close();
        }
    }
}

@@ -858,16 +858,39 @@
 tStream;
+%0Aimport java.util.List;
 %0A%0A/**%0A *
@@ -1270,92 +1270,8 @@
 ();%0A
-        EntityManager entityManager2 = EntityManagerListener.createEntityManager();%0A
     
@@ -1463,38 +1463,9 @@
     
-final EntityTransaction finalT
+t
 rans
@@ -1505,52 +1505,8 @@
 ();%0A
-            transaction = finalTransaction;%0A
     
@@ -1577,36 +1577,8 @@
 a l 
-WHERE l.replacement IS NULL 
 ORDE
@@ -2223,16 +2223,112 @@
 Array();
+%0A                    EntityManager entityManager2 = EntityManagerListener.createEntityManager();
 %0A%0A      
@@ -2394,19 +2394,29 @@
     
+List%3C
 Lemma
+%3E
  lemma
+List
  = e
@@ -2432,41 +2432,262 @@
 ger2
-.find(Lemma.class, results.get(0)
+%0A                                .createQuery(%22SELECT l FROM Lemma l WHERE l.replacement IS NULL AND id = :id%22,%0A                                        Lemma.class)%0A                                .setParameter(%22id%22, results.getInteger(0)).getResultList(
 );%0A%0A
@@ -2718,30 +2718,28 @@
 if (
+!
 lemma
- instanceof Lemma
+List.isEmpty()
 ) %7B%0A
@@ -2797,16 +2797,27 @@
 ct(lemma
+List.get(0)
 );%0A     
@@ -2827,34 +2827,58 @@
                 
-%7D%0A
+    jsonGenerator.flush();
 %0A               
@@ -2890,31 +2890,9 @@
     
-entityManager2.clear();
+%7D
 %0A   
@@ -3149,21 +3149,27 @@
         
-final
+session.get
 Transact
@@ -3171,16 +3171,18 @@
 nsaction
+()
 .commit(

Simplify code and enhance performance in class LemmaResource.