From a2b310e5a211a090995a152fdac1a1e83aa08a23 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 13 May 2015 10:18:45 +0200 Subject: [PATCH] OGM-717 Adding support for @Type(type = "true_false") --- .../impl/CharMappedGridTypeDescriptor.java | 35 ++++++ .../ogm/type/impl/TrueFalseType.java | 35 ++++++ .../ogm/type/impl/TypeTranslatorImpl.java | 1 + .../ogm/backendtck/type/Bookmark.java | 13 +++ .../ogm/backendtck/type/BuiltInTypeTest.java | 23 ++-- .../test/mapping/BuiltinTypeMappingTest.java | 107 ++++++++++++++++++ .../mongodb/utils/MongoDBTestHelper.java | 7 +- 7 files changed, 212 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/org/hibernate/ogm/type/descriptor/impl/CharMappedGridTypeDescriptor.java create mode 100644 core/src/main/java/org/hibernate/ogm/type/impl/TrueFalseType.java create mode 100644 mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/mapping/BuiltinTypeMappingTest.java diff --git a/core/src/main/java/org/hibernate/ogm/type/descriptor/impl/CharMappedGridTypeDescriptor.java b/core/src/main/java/org/hibernate/ogm/type/descriptor/impl/CharMappedGridTypeDescriptor.java new file mode 100644 index 0000000000..939805743f --- /dev/null +++ b/core/src/main/java/org/hibernate/ogm/type/descriptor/impl/CharMappedGridTypeDescriptor.java @@ -0,0 +1,35 @@ +/* + * Hibernate OGM, Domain model persistence for NoSQL datastores + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.ogm.type.descriptor.impl; + +import org.hibernate.ogm.model.spi.Tuple; +import org.hibernate.type.descriptor.WrapperOptions; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + +/** + * Maps a field to a {@link Character} value. + * + * @author Gunnar Morling + */ +public class CharMappedGridTypeDescriptor implements GridTypeDescriptor { + public static final CharMappedGridTypeDescriptor INSTANCE = new CharMappedGridTypeDescriptor(); + + @Override + public GridValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) { + return new BasicGridBinder(javaTypeDescriptor, this) { + @Override + protected void doBind(Tuple resultset, X value, String[] names, WrapperOptions options) { + resultset.put( names[0], javaTypeDescriptor.unwrap( value, Character.class, options ) ); + } + }; + } + + @Override + public GridValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) { + return new BasicGridExtractor( javaTypeDescriptor, true ); + } +} diff --git a/core/src/main/java/org/hibernate/ogm/type/impl/TrueFalseType.java b/core/src/main/java/org/hibernate/ogm/type/impl/TrueFalseType.java new file mode 100644 index 0000000000..e51f60cd17 --- /dev/null +++ b/core/src/main/java/org/hibernate/ogm/type/impl/TrueFalseType.java @@ -0,0 +1,35 @@ +/* + * Hibernate OGM, Domain model persistence for NoSQL datastores + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.ogm.type.impl; + +import org.hibernate.MappingException; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.ogm.type.descriptor.impl.CharMappedGridTypeDescriptor; + +/** + * Maps {@link Boolean} to {@code T} or {@code F} characters. + * + * @author Gunnar Morling + */ +public class TrueFalseType extends AbstractGenericBasicType { + + public static final TrueFalseType INSTANCE = new TrueFalseType(); + + public TrueFalseType() { + super( CharMappedGridTypeDescriptor.INSTANCE, org.hibernate.type.TrueFalseType.INSTANCE.getJavaTypeDescriptor() ); + } + + @Override + public int getColumnSpan(Mapping mapping) throws MappingException { + return 1; + } + + @Override + public String getName() { + return "true_false"; + } +} diff --git a/core/src/main/java/org/hibernate/ogm/type/impl/TypeTranslatorImpl.java b/core/src/main/java/org/hibernate/ogm/type/impl/TypeTranslatorImpl.java index d1424e8641..fc1b74eb24 100644 --- a/core/src/main/java/org/hibernate/ogm/type/impl/TypeTranslatorImpl.java +++ b/core/src/main/java/org/hibernate/ogm/type/impl/TypeTranslatorImpl.java @@ -70,6 +70,7 @@ public TypeTranslatorImpl(GridDialect dialect) { tmpMap.put( BigDecimalTypeDescriptor.INSTANCE, BigDecimalType.INSTANCE ); tmpMap.put( BigIntegerTypeDescriptor.INSTANCE, BigIntegerType.INSTANCE ); tmpMap.put( BooleanTypeDescriptor.INSTANCE, BooleanType.INSTANCE ); + tmpMap.put( TrueFalseType.INSTANCE.getJavaTypeDescriptor(), TrueFalseType.INSTANCE ); tmpMap.put( ByteTypeDescriptor.INSTANCE, ByteType.INSTANCE ); tmpMap.put( JdbcDateTypeDescriptor.INSTANCE, DateType.INSTANCE ); tmpMap.put( JdbcTimestampTypeDescriptor.INSTANCE, TimestampType.INSTANCE ); diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/type/Bookmark.java b/core/src/test/java/org/hibernate/ogm/backendtck/type/Bookmark.java index c526d13648..eaed754d99 100644 --- a/core/src/test/java/org/hibernate/ogm/backendtck/type/Bookmark.java +++ b/core/src/test/java/org/hibernate/ogm/backendtck/type/Bookmark.java @@ -12,6 +12,7 @@ import java.util.Calendar; import java.util.Date; import java.util.UUID; + import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -22,6 +23,7 @@ import javax.persistence.TemporalType; import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; /** * Test entity containing the data types each data store needs to handle. @@ -52,6 +54,9 @@ public enum Classifier { private Boolean favourite; private Byte displayMask; + @Type(type = "true_false") + private boolean isPrivate; + // byte arrays @Lob private byte[] lob; @@ -154,6 +159,14 @@ public Boolean getFavourite() { return favourite; } + public void setPrivate(boolean isPrivate) { + this.isPrivate = isPrivate; + } + + public boolean isPrivate() { + return isPrivate; + } + public Byte getDisplayMask() { return displayMask; } diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/type/BuiltInTypeTest.java b/core/src/test/java/org/hibernate/ogm/backendtck/type/BuiltInTypeTest.java index 5a4140c5ca..8be7366e3c 100644 --- a/core/src/test/java/org/hibernate/ogm/backendtck/type/BuiltInTypeTest.java +++ b/core/src/test/java/org/hibernate/ogm/backendtck/type/BuiltInTypeTest.java @@ -6,6 +6,9 @@ */ package org.hibernate.ogm.backendtck.type; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; @@ -15,18 +18,14 @@ import java.util.TimeZone; import java.util.UUID; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.ogm.backendtck.type.Bookmark.Classifier; import org.hibernate.ogm.utils.OgmTestCase; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; /** * @author Emmanuel Bernard <emmanuel@hibernate.org> @@ -126,6 +125,14 @@ public void testBooleanSupport() throws Exception { assertEquals( "Boolean value does not match", bookmark.getFavourite(), loadedBookmark.getFavourite() ); } + @Test + public void testTrueFalseMappedBooleanSupport() throws Exception { + bookmark.setPrivate( true ); + + Bookmark loadedBookmark = saveAndGet( bookmark ); + assertEquals( "Boolean value does not match", bookmark.isPrivate(), loadedBookmark.isPrivate() ); + } + @Test public void testByteSupport() throws Exception { bookmark.setDisplayMask( (byte) '8' ); diff --git a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/mapping/BuiltinTypeMappingTest.java b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/mapping/BuiltinTypeMappingTest.java new file mode 100644 index 0000000000..35a9080a49 --- /dev/null +++ b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/mapping/BuiltinTypeMappingTest.java @@ -0,0 +1,107 @@ +/* + * Hibernate OGM, Domain model persistence for NoSQL datastores + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.ogm.datastore.mongodb.test.mapping; + +import static org.hibernate.ogm.datastore.mongodb.utils.MongoDBTestHelper.assertDbObject; + +import org.hibernate.Transaction; +import org.hibernate.ogm.OgmSession; +import org.hibernate.ogm.backendtck.type.Bookmark; +import org.hibernate.ogm.utils.OgmTestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for the mappings of built-in types into MongoDB. + * + * @author Gunnar Morling + */ +public class BuiltinTypeMappingTest extends OgmTestCase { + + private String bookmarkId; + + @Before + public void setUpTestData() { + OgmSession session = openSession(); + Transaction transaction = session.beginTransaction(); + + Bookmark bookmark = new Bookmark(); + bookmark.setFavourite( Boolean.TRUE ); + bookmark.setPrivate( true ); + + session.persist( bookmark ); + transaction.commit(); + session.close(); + + this.bookmarkId = bookmark.getId(); + } + + @After + public void removeTestData() { + OgmSession session = openSession(); + Transaction transaction = session.beginTransaction(); + + session.delete( session.get( Bookmark.class, bookmarkId ) ); + + transaction.commit(); + session.close(); + } + + @Test + public void booleanMapping() { + OgmSession session = openSession(); + Transaction transaction = session.beginTransaction(); + + assertDbObject( + session.getSessionFactory(), + // collection + "Bookmark", + // query + "{ '_id' : '" + bookmarkId + "' }", + // fields + "{ 'favourite' : '1' }", + // expected + "{ " + + "'_id' : '" + bookmarkId + "', " + + "'favourite' : true" + + "}" + ); + + transaction.commit(); + session.close(); + } + + @Test + public void trueFalseTypeMapping() { + OgmSession session = openSession(); + Transaction transaction = session.beginTransaction(); + + assertDbObject( + session.getSessionFactory(), + // collection + "Bookmark", + // query + "{ '_id' : '" + bookmarkId + "' }", + // fields + "{ 'isPrivate' : '1' }", + // expected + "{ " + + "'_id' : '" + bookmarkId + "', " + + "'isPrivate' : 'T'" + + "}" + ); + + transaction.commit(); + session.close(); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Bookmark.class }; + } +} diff --git a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/utils/MongoDBTestHelper.java b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/utils/MongoDBTestHelper.java index 9f1663d870..0a7d64f29d 100644 --- a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/utils/MongoDBTestHelper.java +++ b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/utils/MongoDBTestHelper.java @@ -267,11 +267,16 @@ public GridDialect getGridDialect(DatastoreProvider datastoreProvider) { } public static void assertDbObject(OgmSessionFactory sessionFactory, String collection, String queryDbObject, String expectedDbObject) { + assertDbObject( sessionFactory, collection, queryDbObject, null, expectedDbObject ); + } + + public static void assertDbObject(OgmSessionFactory sessionFactory, String collection, String queryDbObject, String projectionDbObject, String expectedDbObject) { DBObject finder = (DBObject) JSON.parse( queryDbObject ); + DBObject fields = projectionDbObject != null ? (DBObject) JSON.parse( projectionDbObject ) : null; DBObject expected = (DBObject) JSON.parse( expectedDbObject ); MongoDBDatastoreProvider provider = MongoDBTestHelper.getProvider( sessionFactory ); - DBObject actual = provider.getDatabase().getCollection( collection ).findOne( finder ); + DBObject actual = provider.getDatabase().getCollection( collection ).findOne( finder, fields ); assertThat( isDBObjectAndContentEqual( actual, expected ) ).describedAs( "Expected: " + expected + " but was: " + actual ).isTrue(); }