/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*/
package org.neo4j.ogm.persistence.session.lifecycle;
import static org.junit.Assert.*;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.ogm.domain.filesystem.Document;
import org.neo4j.ogm.domain.filesystem.Folder;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.neo4j.ogm.testutil.MultiDriverTestClass;
/**
* These tests define the behaviour of the OGM with regard to
* stale object detection.
* <p/>
* The actual test cases are the same as the ones in DegenerateEntityModelTests
* which are known to correctly register the underlying database.
* <p/>
* Because the OGM uses an object cache (to detect dirty objects, and/or deleted
* relationships), we must ensure that changes to the database by a save() are always
* accurately reflected by the corresponding get()
* <p/>
* Example:
* <p/>
* f: { name: 'f', documents : [ { name: 'a'}, { name: 'b' } ] }
* a: { name: 'a', folder : { name: 'f' }}
* b: { name: 'b', folder : { name: 'f' }}
* <p/>
* If we now deleted 'a's reference to 'f' and saved a, we should
* expect that when we retrieve 'f' it won't hold a reference to 'a'
* any longer.
*
* @author Vince Bickers
*/
public class StaleObjectTest extends MultiDriverTestClass {
private Folder f;
private Document a;
private Document b;
private Session session;
@Before
public void init() throws IOException {
SessionFactory sessionFactory = new SessionFactory(getBaseConfiguration().build(), "org.neo4j.ogm.domain.filesystem");
session = sessionFactory.openSession();
a = new Document();
a.setName("a");
b = new Document();
b.setName("b");
f = new Folder();
f.setName("f");
f.getDocuments().add(a);
f.getDocuments().add(b);
a.setFolder(f);
b.setFolder(f);
session.save(f);
assertEquals("Document{folder=Folder{name='f', documents=2, archived=0}, name='a'}", a.toString());
assertEquals("Document{folder=Folder{name='f', documents=2, archived=0}, name='b'}", b.toString());
}
@Test
public void testSaveDegenerateDocument() {
// note that we don't clear the current folder object.
a.setFolder(null);
session.save(a);
Folder p = session.load(Folder.class, f.getId());
assertEquals("Folder{name='f', documents=1, archived=0}", p.toString());
// the document object loaded into the session by virtue of reloading f is no longer b. we guarantee to fetch the latest version of all reachable objects
// and we overwrite objects in the mapping context.
// directly after a save all objects in the save tree are guaranteed to not be dirty
// directly after a load, all objects in the load tree are guaranteed to not be dirty
assertFalse(p.getDocuments().iterator().next() == b);
assertEquals("Document{folder=null, name='a'}", a.toString());
assertEquals("Document{folder=Folder{name='f', documents=2, archived=0}, name='b'}", b.toString()); // b is attached to f, which hasn't been saved or reloaded, so is unchanged
assertEquals("Document{folder=Folder{name='f', documents=1, archived=0}, name='b'}", p.getDocuments().iterator().next().toString());
}
@Test
public void testSaveDegenerateFolder() {
// note that we don't clear any of the document object's folder references.
f.getDocuments().clear();
session.save(f);
assertEquals("Folder{name='f', documents=0, archived=0}", f.toString());
assertEquals("Document{folder=Folder{name='f', documents=0, archived=0}, name='a'}", a.toString());
assertEquals("Document{folder=Folder{name='f', documents=0, archived=0}, name='b'}", b.toString());
Document aa = session.load(Document.class, a.getId());
Document bb = session.load(Document.class, b.getId());
assertEquals("Document{folder=null, name='a'}", aa.toString());
assertEquals("Document{folder=null, name='b'}", bb.toString());
}
}