/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.test.tide.hibernate4.data; import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import org.granite.config.GraniteConfig; import org.granite.config.flex.ServicesConfig; import org.granite.context.SimpleGraniteContext; import org.granite.test.tide.data.AbstractEntity; import org.granite.test.tide.data.Address; import org.granite.test.tide.data.Classification; import org.granite.test.tide.data.Contact4; import org.granite.test.tide.data.Country; import org.granite.test.tide.data.LegalEntity; import org.granite.test.tide.data.LineItemBag; import org.granite.test.tide.data.LineItemBag2; import org.granite.test.tide.data.LineItemList; import org.granite.test.tide.data.LineItemList2; import org.granite.test.tide.data.Order; import org.granite.test.tide.data.Order2; import org.granite.test.tide.data.Person4; import org.granite.test.tide.data.Phone2; import org.granite.test.tide.data.Phone4; import org.granite.tide.data.Change; import org.granite.tide.data.ChangeRef; import org.granite.tide.data.ChangeSet; import org.granite.tide.data.ChangeSetApplier; import org.granite.tide.data.CollectionChange; import org.granite.tide.data.CollectionChanges; import org.granite.tide.data.DataContext; import org.granite.tide.data.DataContext.EntityUpdate; import org.granite.tide.data.DataEnabled.PublishMode; import org.granite.tide.data.DefaultDataDispatcher; import org.granite.tide.data.DefaultDataTopicParams; import org.granite.tide.data.TidePersistenceAdapter; import org.granite.tide.hibernate4.Hibernate4ChangeSetIntegrator; import org.granite.tide.hibernate4.HibernatePersistenceAdapter; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.internal.PersistentList; import org.hibernate.criterion.Restrictions; import org.hibernate.service.ServiceRegistry; import org.junit.Assert; import org.junit.Test; public abstract class TestHibernate4ChangeSetPublisher { private SessionFactory sessionFactory; private Session session; private Transaction tx; protected void initPersistence() { Configuration configuration = new Configuration() .addAnnotatedClass(AbstractEntity.class) .addAnnotatedClass(LegalEntity.class) .addAnnotatedClass(Address.class) .addAnnotatedClass(Contact1.class) .addAnnotatedClass(Country.class) .addAnnotatedClass(Person1.class) .addAnnotatedClass(Person4.class) .addAnnotatedClass(Contact4.class) .addAnnotatedClass(Phone.class) .addAnnotatedClass(Phone2.class) .addAnnotatedClass(Phone4.class) .addAnnotatedClass(OrderRepo.class) .addAnnotatedClass(Order.class) .addAnnotatedClass(LineItemList.class) .addAnnotatedClass(LineItemBag.class) .addAnnotatedClass(Order2.class) .addAnnotatedClass(LineItemList2.class) .addAnnotatedClass(LineItemBag2.class) .addAnnotatedClass(Classification.class) .setProperty("hibernate.dialect", org.hibernate.dialect.H2Dialect.class.getName()) .setProperty("hibernate.hbm2ddl.auto", "create-drop") .setProperty("hibernate.show_sql", "true") .setProperty("hibernate.connection.driver_class", org.h2.Driver.class.getName()) .setProperty("hibernate.connection.url", "jdbc:h2:mem:test-changeset") .setProperty("hibernate.connection.username", "sa") .setProperty("hibernate.connection.password", ""); BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder().with(new Hibernate4ChangeSetIntegrator()); StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(bsrb.build()).applySettings(configuration.getProperties()); ServiceRegistry serviceRegistry = ssrb.build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } protected abstract void setListeners(SessionFactory sessionFactory); protected void open() { session = sessionFactory.openSession(); tx = session.beginTransaction(); } @SuppressWarnings("unchecked") protected <T> T find(Class<T> entityClass, Serializable id) { Criteria criteria = session.createCriteria(entityClass); criteria.add(Restrictions.idEq(id)); return (T)criteria.uniqueResult(); } protected <T> T save(T entity) { session.save(entity); return entity; } protected <T> void delete(T entity) { session.delete(entity); } protected void flush() { session.flush(); tx.commit(); } protected void flushOnly() { session.flush(); } protected void close() { session.clear(); session.close(); } protected TidePersistenceAdapter newPersistenceAdapter() { return new HibernatePersistenceAdapter(session); } @Test public void testSimpleChanges() throws Exception { initPersistence(); Person1 p = new Person1(null, null, "P1"); p.setFirstName("test"); p.setLastName("test"); p.setContacts(new HashSet<Contact1>()); Address a = new Address(null, null, "A1"); Contact1 c = new Contact1(null, null, "C1"); c.setEmail("toto@tutu.net"); c.setAddress(a); c.setPerson(p); p.getContacts().add(c); open(); p = save(p); flush(); Long personId = p.getId(); close(); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); p = find(Person1.class, personId); p.setLastName("toto"); flushOnly(); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); Assert.assertEquals("Updates size", 1, updates.size()); EntityUpdate update = updates.get(0); Assert.assertEquals("Update value", "toto", ((Change)update.entity).getChanges().get("lastName")); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); p = find(Person1.class, personId); a = new Address(null, null, "A2"); c = new Contact1(null, null, "C2"); c.setEmail("toto2@tutu.net"); c.setAddress(a); c.setPerson(p); p.getContacts().add(c); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Person1.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates person", update); CollectionChanges collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("contacts"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); CollectionChange collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof Contact1); Assert.assertEquals("Update coll value", c.getEmail(), ((Contact1)collChange.getValue()).getEmail()); } // @SuppressWarnings({"unchecked", "unused"}) // @Ignore("Cannot make this kind of mapping work with Hibernate: @OneToMany(mappedBy='bla', orphanRemoval=true) + @OrderColumn") // @Test // public void testInverseListChanges() throws Exception { // initPersistence(); // // Order o = new Order(null, null, "O1"); // o.setLineItemsList(new PersistentList(null, new ArrayList<LineItemBag>())); // o.setDescription("order 1"); // LineItemList i1 = new LineItemList(null, null, "I1"); // i1.setDescription("item 1"); // i1.setOrder(o); // o.getLineItemsList().add(i1); // open(); // o = save(o); // flush(); // Long orderId = o.getId(); // close(); // // DataContext.remove(); // DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); // // open(); // o = find(Order.class, orderId); // LineItemList i2 = new LineItemList(null, null, "I2"); // i2.setDescription("item 2"); // i2.setOrder(o); // o.getLineItemsList().add(i2); // flush(); // close(); // // List<EntityUpdate> updates = DataContext.get().getDataUpdates(); // EntityUpdate update = null; // for (EntityUpdate u : updates) { // if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { // update = u; // break; // } // } // Assert.assertNotNull("Updates order", update); // CollectionChanges collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); // Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); // CollectionChange collChange = collChanges.getChanges()[0]; // Assert.assertEquals("Update coll add", 1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList); // Assert.assertEquals("Update coll value", i2.getDescription(), ((LineItemList)collChange.getValue()).getDescription()); // // DataContext.remove(); // DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); // // open(); // o = find(Order.class, orderId); // LineItemList i3 = new LineItemList(null, null, "I3"); // i3.setDescription("item 3"); // i3.setOrder(o); // o.getLineItemsList().add(1, i3); // flush(); // close(); // // updates = DataContext.get().getDataUpdates(); // update = null; // for (EntityUpdate u : updates) { // if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { // update = u; // break; // } // } // Assert.assertNotNull("Updates order", update); // collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); // Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); // collChange = collChanges.getChanges()[0]; // Assert.assertEquals("Update coll add", 1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList); // Assert.assertEquals("Update coll index", 1, collChange.getKey()); // Assert.assertEquals("Update coll value", i3.getDescription(), ((LineItemList)collChange.getValue()).getDescription()); // // DataContext.remove(); // DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); // // open(); // o = find(Order.class, orderId); // LineItemList li = o.getLineItemsList().remove(1); //// delete(li); // flush(); // close(); // // updates = DataContext.get().getDataUpdates(); // update = null; // for (EntityUpdate u : updates) { // if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { // update = u; // break; // } // } // Assert.assertNotNull("Updates order", update); // collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); // Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); // collChange = collChanges.getChanges()[0]; // Assert.assertEquals("Update coll add", -1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList); // Assert.assertEquals("Update coll index", 1, collChange.getKey()); // Assert.assertEquals("Update coll value", i3.getDescription(), ((LineItemList)collChange.getValue()).getDescription()); // // DataContext.remove(); // DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); // // open(); // o = find(Order.class, orderId); // LineItemList i4 = new LineItemList(null, null, "I4"); // i4.setDescription("item 4"); // i4.setOrder(o); // o.getLineItemsList().add(1, i4); // li = o.getLineItemsList().remove(0); //// delete(li); // flush(); // close(); // // updates = DataContext.get().getDataUpdates(); // update = null; // for (EntityUpdate u : updates) { // if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { // update = u; // break; // } // } // Assert.assertNotNull("Updates order", update); // collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); // Assert.assertEquals("Update collection", 2, collChanges.getChanges().length); // collChange = collChanges.getChanges()[0]; // Assert.assertEquals("Update coll add", 1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList); // Assert.assertEquals("Update coll index", 1, collChange.getKey()); // Assert.assertEquals("Update coll value", i4.getDescription(), ((LineItemList)collChange.getValue()).getDescription()); // collChange = collChanges.getChanges()[1]; // Assert.assertEquals("Update coll remove", -1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList); // Assert.assertEquals("Update coll index", 0, collChange.getKey()); // Assert.assertEquals("Update coll value", i1.getDescription(), ((LineItemList)collChange.getValue()).getDescription()); // } @SuppressWarnings("unchecked") @Test public void testInverseBagChanges() throws Exception { initPersistence(); Order o = new Order(null, null, "O1"); o.setLineItemsBag(new PersistentBag(null, new ArrayList<LineItemBag>())); o.setDescription("order 1"); LineItemBag i1 = new LineItemBag(null, null, "I1"); i1.setDescription("item 1"); i1.setOrder(o); o.getLineItemsBag().add(0, i1); open(); o = save(o); flush(); Long orderId = o.getId(); close(); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order.class, orderId); LineItemBag i2 = new LineItemBag(null, null, "I2"); i2.setDescription("item 2"); i2.setOrder(o); o.getLineItemsBag().add(i2); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); EntityUpdate update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); CollectionChanges collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsBag"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); CollectionChange collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemBag); Assert.assertEquals("Update coll value", i2.getDescription(), ((LineItemBag)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order.class, orderId); LineItemBag i3 = new LineItemBag(null, null, "I3"); i3.setDescription("item 3"); i3.setOrder(o); o.getLineItemsBag().add(1, i3); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsBag"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemBag); Assert.assertEquals("Update coll index", 1, collChange.getKey()); Assert.assertEquals("Update coll value", i3.getDescription(), ((LineItemBag)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order.class, orderId); o.getLineItemsBag().remove(1); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsBag"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", -1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemBag); Assert.assertEquals("Update coll index", 1, collChange.getKey()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order.class, orderId); LineItemBag i4 = new LineItemBag(null, null, "I4"); i4.setDescription("item 4"); o.getLineItemsBag().add(1, i4); o.getLineItemsBag().remove(0); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsBag"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll update", 0, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemBag); Assert.assertEquals("Update coll index", 0, collChange.getKey()); Assert.assertEquals("Update coll value", i4.getDescription(), ((LineItemBag)collChange.getValue()).getDescription()); } @SuppressWarnings("unchecked") @Test public void testListChanges() throws Exception { initPersistence(); Order2 o = new Order2(null, null, "O1"); o.setLineItemsList(new PersistentList(null, new ArrayList<LineItemList2>())); o.setDescription("order 1"); LineItemList2 i1 = new LineItemList2(null, null, "I1"); i1.setDescription("item 1"); o.getLineItemsList().add(i1); open(); o = save(o); flush(); Long orderId = o.getId(); close(); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order2.class, orderId); LineItemList2 i2 = new LineItemList2(null, null, "I2"); i2.setDescription("item 2"); o.getLineItemsList().add(i2); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); EntityUpdate update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order2.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); CollectionChanges collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); CollectionChange collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList2); Assert.assertEquals("Update coll index", 1, collChange.getKey()); Assert.assertEquals("Update coll value", i2.getDescription(), ((LineItemList2)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order2.class, orderId); LineItemList2 i3 = new LineItemList2(null, null, "I3"); i3.setDescription("item 3"); o.getLineItemsList().add(1, i3); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order2.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList2); Assert.assertEquals("Update coll index", 1, collChange.getKey()); Assert.assertEquals("Update coll value", i3.getDescription(), ((LineItemList2)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); o = find(Order2.class, orderId); o.getLineItemsList().remove(1); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order2.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates order", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", -1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList2); Assert.assertEquals("Update coll index", 1, collChange.getKey()); Assert.assertEquals("Update coll value", i3.getDescription(), ((LineItemList2)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); // Cannot make this work with Hibernate 3.6.5.Final // JDBC Exception: failed batch ??? // open(); // o = find(Order2.class, orderId); // LineItemList2 i4 = new LineItemList2(null, null, "I4"); // i4.setDescription("item 4"); // o.getLineItemsList().add(i4); // o.getLineItemsList().remove(0); // flush(); // close(); // // updates = DataContext.get().getDataUpdates(); // update = null; // for (EntityUpdate u : updates) { // if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Order2.class.getName())) { // update = u; // break; // } // } // Assert.assertNotNull("Updates order", update); // collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("lineItemsList"); // Assert.assertEquals("Update collection", 2, collChanges.getChanges().length); // collChange = collChanges.getChanges()[0]; // Assert.assertEquals("Update coll remove", -1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList2); // Assert.assertEquals("Update coll index", 0, collChange.getKey()); // Assert.assertEquals("Update coll value", i1.getDescription(), ((LineItemList2)collChange.getValue()).getDescription()); // collChange = collChanges.getChanges()[1]; // Assert.assertEquals("Update coll add", 1, collChange.getType()); // Assert.assertTrue("Update coll type", collChange.getValue() instanceof LineItemList2); // Assert.assertEquals("Update coll index", 1, collChange.getKey()); // Assert.assertEquals("Update coll value", i4.getDescription(), ((LineItemList2)collChange.getValue()).getDescription()); } @Test public void testMapChanges() throws Exception { initPersistence(); OrderRepo r = new OrderRepo(null, null, "R1"); r.setDescription("repo 1"); Order o1 = new Order(null, null, "O1"); o1.setDescription("order 1"); r.getOrders().put(o1.getDescription(), o1); open(); r = save(r); flush(); Long repoId = r.getId(); close(); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); r = find(OrderRepo.class, repoId); Order o2 = new Order(null, null, "O2"); o2.setDescription("order 2"); r.getOrders().put(o2.getDescription(), o2); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); EntityUpdate update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(OrderRepo.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates repo", update); CollectionChanges collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("orders"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); CollectionChange collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll add", 1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof Order); Assert.assertEquals("Update coll index", o2.getDescription(), collChange.getKey()); Assert.assertEquals("Update coll value", o2.getDescription(), ((Order)collChange.getValue()).getDescription()); DataContext.remove(); DataContext.init(new DefaultDataDispatcher(null, "testTopic", DefaultDataTopicParams.class), PublishMode.MANUAL); open(); r = find(OrderRepo.class, repoId); r.getOrders().remove(o1.getDescription()); flush(); close(); updates = DataContext.get().getDataUpdates(); update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(OrderRepo.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates repo", update); collChanges = (CollectionChanges)((Change)update.entity).getChanges().get("orders"); Assert.assertEquals("Update collection", 1, collChanges.getChanges().length); collChange = collChanges.getChanges()[0]; Assert.assertEquals("Update coll remove", -1, collChange.getType()); Assert.assertTrue("Update coll type", collChange.getValue() instanceof Order); Assert.assertEquals("Update coll index", o1.getDescription(), collChange.getKey()); Assert.assertEquals("Update coll value", o1.getDescription(), ((Order)collChange.getValue()).getDescription()); } @SuppressWarnings("unchecked") @Test public void testReorderList2() throws Exception { initPersistence(); open(); Classification p = new Classification(null, null, "P1"); p.setCode("P1"); p.setSubClassifications(new PersistentList(null, new ArrayList<Classification>())); Classification c1 = new Classification(null, null, "C1"); c1.setCode("C1"); Classification c2 = new Classification(null, null, "C2"); c2.setCode("C2"); Classification c3 = new Classification(null, null, "C3"); c3.setCode("C3"); Classification c4 = new Classification(null, null, "C4"); c4.setCode("C4"); p.getSubClassifications().add(c1); p.getSubClassifications().add(c2); p.getSubClassifications().add(c3); p.getSubClassifications().add(c4); p = save(p); flush(); Long pId = p.getId(); Long c4Id = p.getSubClassifications().get(3).getId(); close(); open(); InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/granite/test/tide/data/enterprise/granite-config.xml"); GraniteConfig graniteConfig = new GraniteConfig(null, is, null, "test"); ServicesConfig servicesConfig = new ServicesConfig(null, null, false); SimpleGraniteContext.createThreadInstance(graniteConfig, servicesConfig, new HashMap<String, Object>()); DataContext.init(null, null, PublishMode.MANUAL); Change change = new Change(Classification.class.getName(), pId, p.getVersion(), p.getUid()); CollectionChange collChange1 = new CollectionChange(-1, 3, new ChangeRef(Classification.class.getName(), "C4", new Integer(c4Id.intValue()))); CollectionChange collChange2 = new CollectionChange(1, 2, new ChangeRef(Classification.class.getName(), "C4", new Integer(c4Id.intValue()))); CollectionChanges collChanges = new CollectionChanges(new CollectionChange[] { collChange1, collChange2 }); change.getChanges().put("subClassifications", collChanges); ChangeSet changeSet = new ChangeSet(new Change[] { change }); new ChangeSetApplier(newPersistenceAdapter()).applyChanges(changeSet); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); Assert.assertEquals("1 update", 1, updates.size()); Assert.assertTrue("Change update", updates.get(0).entity instanceof Change); Change ch = (Change)updates.get(0).entity; CollectionChanges cch = (CollectionChanges)ch.getChanges().get("subClassifications"); Assert.assertEquals("Coll changes", 2, cch.getChanges().length); Assert.assertEquals("Coll change 1 del", -1, cch.getChanges()[0].getType()); Assert.assertEquals("Coll change 2 add", 1, cch.getChanges()[1].getType()); } @Test public void testInheritedSetChanges() throws Exception { initPersistence(); Person4 p = new Person4(null, null, "P1"); p.setPhones(new ArrayList<Phone4>()); Phone4 ph = new Phone4(null, null, "PH1"); ph.setPhone("01 01 01 01 01"); ph.setLegalEntity(p); p.getPhones().add(ph); open(); p = save(p); flush(); Long pId = p.getId(); close(); DataContext.init(null, null, PublishMode.MANUAL); open(); p = find(Person4.class, pId); Phone4 ph2 = new Phone4(null, null, "PH2"); ph2.setPhone("02 02 02 02 02"); ph2.setLegalEntity(p); p.getPhones().add(ph2); flush(); close(); List<EntityUpdate> updates = DataContext.get().getDataUpdates(); updates = DataContext.get().getDataUpdates(); EntityUpdate update = null; for (EntityUpdate u : updates) { if (u.entity instanceof Change && ((Change)u.entity).getClassName().equals(Person4.class.getName())) { update = u; break; } } Assert.assertNotNull("Updates person", update); Assert.assertTrue("Change update", update.entity instanceof Change); Change ch = (Change)update.entity; CollectionChanges cch = (CollectionChanges)ch.getChanges().get("phones"); Assert.assertEquals("Coll changes", 1, cch.getChanges().length); Assert.assertEquals("Coll change 2 add", 1, cch.getChanges()[0].getType()); } }