package org.mongodb.morphia; import org.bson.types.ObjectId; import org.junit.Assert; import org.junit.Test; import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.PostLoad; import org.mongodb.morphia.annotations.Property; import org.mongodb.morphia.annotations.Reference; import org.mongodb.morphia.mapping.EmbeddedMappingTest.AnotherNested; import org.mongodb.morphia.mapping.EmbeddedMappingTest.Nested; import org.mongodb.morphia.mapping.EmbeddedMappingTest.NestedImpl; import org.mongodb.morphia.mapping.MappedClass; import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.mapping.lazy.LazyFeatureDependencies; import java.io.Serializable; import java.util.List; import static java.util.Arrays.asList; /** * Tests mapper functions; this is tied to some of the internals. * * @author scotthernandez */ public class TestMapper extends TestBase { @Test public void serializableId() throws Exception { final CustomId cId = new CustomId(); cId.id = new ObjectId(); cId.type = "banker"; final UsesCustomIdObject object = new UsesCustomIdObject(); object.id = cId; object.text = "hllo"; getDs().save(object); } @Test public void singleLookup() throws Exception { A.loadCount = 0; final A a = new A(); HoldsMultipleA holder = new HoldsMultipleA(); holder.a1 = a; holder.a2 = a; getDs().save(asList(a, holder)); holder = getDs().get(HoldsMultipleA.class, holder.id); Assert.assertEquals(1, A.loadCount); Assert.assertTrue(holder.a1 == holder.a2); } @Test public void singleProxy() throws Exception { // TODO us: exclusion does not work properly with maven + junit4 if (!LazyFeatureDependencies.testDependencyFullFilled()) { return; } A.loadCount = 0; final A a = new A(); HoldsMultipleALazily holder = new HoldsMultipleALazily(); holder.a1 = a; holder.a2 = a; holder.a3 = a; getDs().save(asList(a, holder)); Assert.assertEquals(0, A.loadCount); holder = getDs().get(HoldsMultipleALazily.class, holder.id); Assert.assertNotNull(holder.a2); Assert.assertEquals(1, A.loadCount); Assert.assertFalse(holder.a1 == holder.a2); // FIXME currently not guaranteed: // Assert.assertTrue(holder.a1 == holder.a3); // A.loadCount=0; // Assert.assertEquals(holder.a1.getId(), holder.a2.getId()); } @Test public void subTypes() { getMorphia().map(NestedImpl.class, AnotherNested.class); Mapper mapper = getMorphia().getMapper(); List<MappedClass> subTypes = mapper.getSubTypes(mapper.getMappedClass(Nested.class)); Assert.assertTrue(subTypes.contains(mapper.getMappedClass(NestedImpl.class))); Assert.assertTrue(subTypes.contains(mapper.getMappedClass(AnotherNested.class))); } public static class A { private static int loadCount; @Id private ObjectId id; @PostLoad protected void postConstruct() { if (loadCount > 1) { throw new RuntimeException(); } loadCount++; } String getId() { return id.toString(); } } @Entity("holders") public static class HoldsMultipleA { @Id private ObjectId id; @Reference private A a1; @Reference private A a2; } @Entity("holders") public static class HoldsMultipleALazily { @Id private ObjectId id; @Reference(lazy = true) private A a1; @Reference private A a2; @Reference(lazy = true) private A a3; } public static class CustomId implements Serializable { @Property("v") private ObjectId id; @Property("t") private String type; public ObjectId getId() { return id; } public void setId(final ObjectId id) { this.id = id; } public String getType() { return type; } public void setType(final String type) { this.type = type; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof CustomId)) { return false; } final CustomId other = (CustomId) obj; if (id == null) { if (other.id != null) { return false; } } else if (!id.equals(other.id)) { return false; } if (type == null) { if (other.type != null) { return false; } } else if (!type.equals(other.type)) { return false; } return true; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("CustomId ["); if (id != null) { builder.append("id=").append(id).append(", "); } if (type != null) { builder.append("type=").append(type); } builder.append("]"); return builder.toString(); } } public static class UsesCustomIdObject { @Id private CustomId id; private String text; public CustomId getId() { return id; } public void setId(final CustomId id) { this.id = id; } public String getText() { return text; } public void setText(final String text) { this.text = text; } } }