| /******************************************************************************* |
| * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 |
| * which accompanies this distribution. |
| * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html |
| * and the Eclipse Distribution License is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * Contributors: |
| * Oracle - initial impl |
| ******************************************************************************/ |
| package example; |
| |
| import java.util.List; |
| |
| import javax.persistence.EntityManager; |
| import javax.persistence.EntityManagerFactory; |
| import javax.persistence.NoResultException; |
| import javax.persistence.Persistence; |
| import javax.persistence.Query; |
| |
| import model.*; |
| |
| /** |
| * Simulates a migration of 100,000 objects from MySQL to Oracle. |
| * @author James Sutherland |
| */ |
| public class TestOptimized extends Test { |
| |
| public static void main(String[] args) throws Exception { |
| // Optimization #1 - use agent |
| try { |
| Test test = new TestOptimized(); |
| test.setupDatabase(); |
| test.migrateDatabase(); |
| test.verifyMigration(); |
| } catch (Exception error) { |
| error.printStackTrace(); |
| } |
| } |
| |
| public void migrateDatabase() { |
| EntityManagerFactory emf = Persistence.createEntityManagerFactory("order-opt"); |
| EntityManagerFactory emfOld = Persistence.createEntityManagerFactory("order-old"); |
| EntityManager emOld = emfOld.createEntityManager(); |
| System.out.println("Migrating database."); |
| long start = System.currentTimeMillis(); |
| Query query = emOld.createQuery("Select o from Order o order by o.id"); |
| // Optimization #2 - batch fetch |
| // #2 - a - join fetch |
| //Query query = emOld.createQuery("Select o from Order o join fetch o.orderLines"); |
| // #2 - b - batch fetch (batch fetch is more optimal as avoids duplication of Order data) |
| query.setHint("eclipselink.batch", "o.orderLines"); |
| query.setHint("eclipselink.batch.type", "IN"); |
| // Optimization #3 - read-only |
| query.setHint("eclipselink.read-only", "true"); |
| // Optimization #4 - pagination |
| int pageSize = 500; |
| int firstResult = 0; |
| query.setFirstResult(firstResult); |
| query.setMaxResults(pageSize); |
| |
| List<Order> orders = query.getResultList(); |
| boolean done = false; |
| while (!done) { |
| if (orders.size() < pageSize) { |
| done = true; |
| } |
| EntityManager em = emf.createEntityManager(); |
| em.getTransaction().begin(); |
| Query customerQuery = em.createNamedQuery("findCustomByName"); |
| // Reset old Ids, so they are assigned from the new database. |
| for (Order order : orders) { |
| order.setId(0); |
| customerQuery.setParameter("name", order.getCustomer().getName()); |
| try { |
| Customer customer = (Customer)customerQuery.getSingleResult(); |
| order.setCustomer(customer); |
| } catch (NoResultException notPersistedYet) { |
| // Customer does not yet exist, so null out id to have it persisted. |
| order.getCustomer().setId(0); |
| } |
| } |
| for (Order order : orders) { |
| em.persist(order); |
| // Optimization #5 - avoid n^2 persist calls |
| //for (OrderLine orderLine : order.getOrderLines()) { |
| // em.persist(orderLine); |
| //} |
| } |
| em.getTransaction().commit(); |
| em.close(); |
| firstResult = firstResult + pageSize; |
| query.setFirstResult(firstResult); |
| if (!done) { |
| orders = query.getResultList(); |
| } |
| } |
| emOld.close(); |
| System.out.println("Migration complete."); |
| long end = System.currentTimeMillis(); |
| System.out.println("Total time:" + (end - start)); |
| emf.close(); |
| emfOld.close(); |
| } |
| } |