You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/09/30 14:23:48 UTC

[2/9] cayenne git commit: CAY-2115 DbLoader - allow loading DataMap without Obj layer

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/DbLoaderIT.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/DbLoaderIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/DbLoaderIT.java
new file mode 100644
index 0000000..930d696
--- /dev/null
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/DbLoaderIT.java
@@ -0,0 +1,418 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.dbsync.reverse.db;
+
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
+import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
+import org.apache.cayenne.dbsync.reverse.filters.TableFilter;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.*;
+import org.apache.cayenne.unit.UnitDbAdapter;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.ServerCaseDataSourceFactory;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.Types;
+import java.util.Collection;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class DbLoaderIT extends ServerCase {
+
+    public static final DbLoaderConfiguration CONFIG = new DbLoaderConfiguration();
+    @Inject
+    private ServerRuntime runtime;
+
+    @Inject
+    private DbAdapter adapter;
+
+    @Inject
+    private ServerCaseDataSourceFactory dataSourceFactory;
+
+    @Inject
+    private UnitDbAdapter accessStackAdapter;
+
+    private DbLoader loader;
+
+    private Connection connection;
+
+    private static String msgForTypeMismatch(DbAttribute origAttr, DbAttribute newAttr) {
+        return msgForTypeMismatch(origAttr.getType(), newAttr);
+    }
+
+    private static String msgForTypeMismatch(int origType, DbAttribute newAttr) {
+        String nt = TypesMapping.getSqlNameByType(newAttr.getType());
+        String ot = TypesMapping.getSqlNameByType(origType);
+        return attrMismatch(newAttr.getName(), "expected type: <" + ot + ">, but was <" + nt + ">");
+    }
+
+    private static String attrMismatch(String attrName, String msg) {
+        return "[Error loading attribute '" + attrName + "': " + msg + "]";
+    }
+
+    @Before
+    public void before() throws Exception {
+        this.connection = dataSourceFactory.getSharedDataSource().getConnection();
+        this.loader = new DbLoader(connection, adapter, null);
+    }
+
+    @After
+    public void after() throws Exception {
+        connection.close();
+    }
+
+    @Test
+    public void testGetTables() throws Exception {
+
+        String tableLabel = adapter.tableTypeForTable();
+
+        List<DetectedDbEntity> tables = loader.createTableLoader(null, null, TableFilter.everything())
+                .getDbEntities(TableFilter.everything(), new String[]{tableLabel});
+
+        assertNotNull(tables);
+
+        boolean foundArtist = false;
+
+        for (DetectedDbEntity table : tables) {
+            if ("ARTIST".equalsIgnoreCase(table.getName())) {
+                foundArtist = true;
+                break;
+            }
+        }
+
+        assertTrue("'ARTIST' is missing from the table list: " + tables, foundArtist);
+    }
+
+    @Test
+    public void testGetTablesWithWrongCatalog() throws Exception {
+
+        DbLoaderConfiguration config = new DbLoaderConfiguration();
+        config.setFiltersConfig(
+                FiltersConfig.create("WRONG", null, TableFilter.everything(), PatternFilter.INCLUDE_NOTHING));
+        List<DetectedDbEntity> tables = loader
+                .createTableLoader("WRONG", null, TableFilter.everything())
+                .getDbEntities(TableFilter.everything(), new String[]{adapter.tableTypeForTable()});
+
+        assertNotNull(tables);
+        assertTrue(tables.isEmpty());
+    }
+
+    @Test
+    public void testGetTablesWithWrongSchema() throws Exception {
+
+        DbLoaderConfiguration config = new DbLoaderConfiguration();
+        config.setFiltersConfig(
+                FiltersConfig.create(null, "WRONG", TableFilter.everything(), PatternFilter.INCLUDE_NOTHING));
+        List<DetectedDbEntity> tables = loader
+                .createTableLoader(null, "WRONG", TableFilter.everything())
+                .getDbEntities(TableFilter.everything(), new String[]{adapter.tableTypeForTable()});
+
+        assertNotNull(tables);
+        assertTrue(tables.isEmpty());
+    }
+
+    @Test
+    public void testLoadWithMeaningfulPK() throws Exception {
+
+        DataMap map = new DataMap();
+        String[] tableLabel = {adapter.tableTypeForTable()};
+
+        loader.setCreatingMeaningfulPK(true);
+
+        List<DbEntity> entities = loader
+                .createTableLoader(null, null, TableFilter.everything())
+                .loadDbEntities(map, CONFIG, tableLabel);
+
+        loader.loadObjEntities(map, CONFIG, entities);
+
+        ObjEntity artist = map.getObjEntity("Artist");
+        assertNotNull(artist);
+
+        ObjAttribute id = artist.getAttribute("artistId");
+        assertNotNull(id);
+    }
+
+    /**
+     * DataMap loading is in one big test method, since breaking it in
+     * individual tests would require multiple reads of metatdata which is
+     * extremely slow on some RDBMS (Sybase).
+     */
+    @Test
+    public void testLoad() throws Exception {
+
+        boolean supportsUnique = runtime.getDataDomain().getDataNodes().iterator().next().getAdapter()
+                .supportsUniqueConstraints();
+        boolean supportsLobs = accessStackAdapter.supportsLobs();
+        boolean supportsFK = accessStackAdapter.supportsFKConstraints();
+
+        DataMap map = new DataMap();
+        map.setDefaultPackage("foo.x");
+
+        String tableLabel = adapter.tableTypeForTable();
+
+        // *** TESTING THIS ***
+        List<DbEntity> entities = loader
+                .createTableLoader(null, null, TableFilter.everything())
+                .loadDbEntities(map, CONFIG, new String[]{adapter.tableTypeForTable()});
+
+
+        assertDbEntities(map);
+
+        if (supportsLobs) {
+            assertLobDbEntities(map);
+        }
+
+        // *** TESTING THIS ***
+        loader.loadDbRelationships(CONFIG, null, null, entities);
+
+        if (supportsFK) {
+            Collection<DbRelationship> rels = getDbEntity(map, "ARTIST").getRelationships();
+            assertNotNull(rels);
+            assertTrue(!rels.isEmpty());
+
+            // test one-to-one
+            rels = getDbEntity(map, "PAINTING").getRelationships();
+            assertNotNull(rels);
+
+            // find relationship to PAINTING_INFO
+            DbRelationship oneToOne = null;
+            for (DbRelationship rel : rels) {
+                if ("PAINTING_INFO".equalsIgnoreCase(rel.getTargetEntityName())) {
+                    oneToOne = rel;
+                    break;
+                }
+            }
+
+            assertNotNull("No relationship to PAINTING_INFO", oneToOne);
+            assertFalse("Relationship to PAINTING_INFO must be to-one", oneToOne.isToMany());
+            assertTrue("Relationship to PAINTING_INFO must be to-one", oneToOne.isToDependentPK());
+
+            // test UNIQUE only if FK is supported...
+            if (supportsUnique) {
+                assertUniqueConstraintsInRelationships(map);
+            }
+        }
+
+        // *** TESTING THIS ***
+        loader.setCreatingMeaningfulPK(false);
+        loader.loadObjEntities(map, CONFIG, entities);
+
+        assertObjEntities(map);
+
+        // now when the map is loaded, test
+        // various things
+        // selectively check how different types were processed
+        if (accessStackAdapter.supportsColumnTypeReengineering()) {
+            checkTypes(map);
+        }
+    }
+
+    private void assertUniqueConstraintsInRelationships(DataMap map) {
+        // unfortunately JDBC metadata doesn't provide info for UNIQUE
+        // constraints....
+        // cant reengineer them...
+
+        // find rel to TO_ONEFK1
+        /*
+         * Iterator it = getDbEntity(map,
+         * "TO_ONEFK2").getRelationships().iterator(); DbRelationship rel =
+         * (DbRelationship) it.next(); assertEquals("TO_ONEFK1",
+         * rel.getTargetEntityName());
+         * assertFalse("UNIQUE constraint was ignored...", rel.isToMany());
+         */
+    }
+
+    private void assertDbEntities(DataMap map) {
+        DbEntity dae = getDbEntity(map, "ARTIST");
+        assertNotNull("Null 'ARTIST' entity, other DbEntities: " + map.getDbEntityMap(), dae);
+        assertEquals("ARTIST", dae.getName().toUpperCase());
+
+        DbAttribute a = getDbAttribute(dae, "ARTIST_ID");
+        assertNotNull(a);
+        assertTrue(a.isPrimaryKey());
+        assertFalse(a.isGenerated());
+
+        if (adapter.supportsGeneratedKeys()) {
+            DbEntity bag = getDbEntity(map, "GENERATED_COLUMN_TEST");
+            DbAttribute id = getDbAttribute(bag, "GENERATED_COLUMN");
+            assertTrue(id.isPrimaryKey());
+            assertTrue(id.isGenerated());
+        }
+    }
+
+    private void assertObjEntities(DataMap map) {
+
+        boolean supportsLobs = accessStackAdapter.supportsLobs();
+        boolean supportsFK = accessStackAdapter.supportsFKConstraints();
+
+        ObjEntity ae = map.getObjEntity("Artist");
+        assertNotNull(ae);
+        assertEquals("Artist", ae.getName());
+
+        // assert primary key is not an attribute
+        assertNull(ae.getAttribute("artistId"));
+
+        if (supportsLobs) {
+            assertLobObjEntities(map);
+        }
+
+        if (supportsFK) {
+            Collection<?> rels1 = ae.getRelationships();
+            assertNotNull(rels1);
+            assertTrue(rels1.size() > 0);
+        }
+
+        assertEquals("foo.x.Artist", ae.getClassName());
+    }
+
+    private void assertLobDbEntities(DataMap map) {
+        DbEntity blobEnt = getDbEntity(map, "BLOB_TEST");
+        assertNotNull(blobEnt);
+        DbAttribute blobAttr = getDbAttribute(blobEnt, "BLOB_COL");
+        assertNotNull(blobAttr);
+        assertTrue(msgForTypeMismatch(Types.BLOB, blobAttr), Types.BLOB == blobAttr.getType()
+                || Types.LONGVARBINARY == blobAttr.getType());
+
+        DbEntity clobEnt = getDbEntity(map, "CLOB_TEST");
+        assertNotNull(clobEnt);
+        DbAttribute clobAttr = getDbAttribute(clobEnt, "CLOB_COL");
+        assertNotNull(clobAttr);
+        assertTrue(msgForTypeMismatch(Types.CLOB, clobAttr), Types.CLOB == clobAttr.getType()
+                || Types.LONGVARCHAR == clobAttr.getType());
+
+/*
+        DbEntity nclobEnt = getDbEntity(map, "NCLOB_TEST");
+        assertNotNull(nclobEnt);
+        DbAttribute nclobAttr = getDbAttribute(nclobEnt, "NCLOB_COL");
+        assertNotNull(nclobAttr);
+        assertTrue(msgForTypeMismatch(Types.NCLOB, nclobAttr), Types.NCLOB == nclobAttr.getType()
+                || Types.LONGVARCHAR == nclobAttr.getType());
+*/
+    }
+
+    private void assertLobObjEntities(DataMap map) {
+        ObjEntity blobEnt = map.getObjEntity("BlobTest");
+        assertNotNull(blobEnt);
+        // BLOBs should be mapped as byte[]
+        ObjAttribute blobAttr = blobEnt.getAttribute("blobCol");
+        assertNotNull("BlobTest.blobCol failed to doLoad", blobAttr);
+        assertEquals("byte[]", blobAttr.getType());
+
+
+        ObjEntity clobEnt = map.getObjEntity("ClobTest");
+        assertNotNull(clobEnt);
+        // CLOBs should be mapped as Strings by default
+        ObjAttribute clobAttr = clobEnt.getAttribute("clobCol");
+        assertNotNull(clobAttr);
+        assertEquals(String.class.getName(), clobAttr.getType());
+
+
+        ObjEntity nclobEnt = map.getObjEntity("NclobTest");
+        assertNotNull(nclobEnt);
+        // CLOBs should be mapped as Strings by default
+        ObjAttribute nclobAttr = nclobEnt.getAttribute("nclobCol");
+        assertNotNull(nclobAttr);
+        assertEquals(String.class.getName(), nclobAttr.getType());
+    }
+
+    private DbEntity getDbEntity(DataMap map, String name) {
+        DbEntity de = map.getDbEntity(name);
+        // sometimes table names get converted to lowercase
+        if (de == null) {
+            de = map.getDbEntity(name.toLowerCase());
+        }
+
+        return de;
+    }
+
+    private DbAttribute getDbAttribute(DbEntity ent, String name) {
+        DbAttribute da = ent.getAttribute(name);
+        // sometimes table names get converted to lowercase
+        if (da == null) {
+            da = ent.getAttribute(name.toLowerCase());
+        }
+
+        return da;
+    }
+
+    private DataMap originalMap() {
+        return runtime.getDataDomain().getDataNodes().iterator().next().getDataMaps().iterator().next();
+    }
+
+    /**
+     * Selectively check how different types were processed.
+     */
+    public void checkTypes(DataMap map) {
+        DbEntity dbe = getDbEntity(map, "PAINTING");
+        DbEntity floatTest = getDbEntity(map, "FLOAT_TEST");
+        DbEntity smallintTest = getDbEntity(map, "SMALLINT_TEST");
+        DbAttribute integerAttr = getDbAttribute(dbe, "PAINTING_ID");
+        DbAttribute decimalAttr = getDbAttribute(dbe, "ESTIMATED_PRICE");
+        DbAttribute varcharAttr = getDbAttribute(dbe, "PAINTING_TITLE");
+        DbAttribute floatAttr = getDbAttribute(floatTest, "FLOAT_COL");
+        DbAttribute smallintAttr = getDbAttribute(smallintTest, "SMALLINT_COL");
+
+        // check decimal
+        assertTrue(msgForTypeMismatch(Types.DECIMAL, decimalAttr), Types.DECIMAL == decimalAttr.getType()
+                || Types.NUMERIC == decimalAttr.getType());
+        assertEquals(2, decimalAttr.getScale());
+
+        // check varchar
+        assertEquals(msgForTypeMismatch(Types.VARCHAR, varcharAttr), Types.VARCHAR, varcharAttr.getType());
+        assertEquals(255, varcharAttr.getMaxLength());
+        // check integer
+        assertEquals(msgForTypeMismatch(Types.INTEGER, integerAttr), Types.INTEGER, integerAttr.getType());
+        // check float
+        assertTrue(msgForTypeMismatch(Types.FLOAT, floatAttr), Types.FLOAT == floatAttr.getType()
+                || Types.DOUBLE == floatAttr.getType() || Types.REAL == floatAttr.getType());
+
+        // check smallint
+        assertTrue(msgForTypeMismatch(Types.SMALLINT, smallintAttr), Types.SMALLINT == smallintAttr.getType()
+                || Types.INTEGER == smallintAttr.getType());
+    }
+
+    public void checkAllDBEntities(DataMap map) {
+
+        for (DbEntity origEnt : originalMap().getDbEntities()) {
+            DbEntity newEnt = map.getDbEntity(origEnt.getName());
+            for (DbAttribute origAttr : origEnt.getAttributes()) {
+                DbAttribute newAttr = newEnt.getAttribute(origAttr.getName());
+                assertNotNull("No matching DbAttribute for '" + origAttr.getName(), newAttr);
+                assertEquals(msgForTypeMismatch(origAttr, newAttr), origAttr.getType(), newAttr.getType());
+                // length and precision doesn't have to be the same
+                // it must be greater or equal
+                assertTrue(origAttr.getMaxLength() <= newAttr.getMaxLength());
+                assertTrue(origAttr.getScale() <= newAttr.getScale());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntityTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntityTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntityTest.java
new file mode 100644
index 0000000..b4ab34c
--- /dev/null
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntityTest.java
@@ -0,0 +1,113 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.dbsync.reverse.db;
+
+import org.apache.cayenne.configuration.ConfigurationNameMapper;
+import org.apache.cayenne.configuration.ConfigurationTree;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataMapLoader;
+import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
+import org.apache.cayenne.configuration.XMLDataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.XMLDataMapLoader;
+import org.apache.cayenne.di.AdhocObjectFactory;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.ClassLoaderManager;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
+import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.map.naming.LegacyNameGenerator;
+import org.apache.cayenne.resource.URLResource;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URL;
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class ManyToManyCandidateEntityTest {
+
+    private DataMap map;
+
+    @Before
+    public void setUp() throws Exception {
+        Module testModule = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
+                binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
+                binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);
+                binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class);
+            }
+        };
+
+        Injector injector = DIBootstrap.createInjector(testModule);
+
+        // create and initialize loader instance to test
+        XMLDataChannelDescriptorLoader loader = new XMLDataChannelDescriptorLoader();
+        injector.injectMembers(loader);
+
+        String testConfigName = "relationship-optimisation";
+        URL url = getClass().getResource("cayenne-" + testConfigName + ".xml");
+
+        ConfigurationTree<DataChannelDescriptor> tree = loader.load(new URLResource(url));
+
+        map = tree.getRootNode().getDataMap(testConfigName);
+    }
+
+    @Test
+    public void testMatchingForManyToManyEntity() throws Exception {
+        ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2");
+
+        assertNotNull(ManyToManyCandidateEntity.build(manyToManyEntity));
+    }
+
+    @Test
+    public void testMatchingForNotManyToManyEntity() throws Exception {
+        ObjEntity entity = map.getObjEntity("Table1");
+
+        assertNull(ManyToManyCandidateEntity.build(entity));
+    }
+
+    @Test
+    public void testOptimisationForManyToManyEntity() {
+        ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2");
+
+        ManyToManyCandidateEntity.build(manyToManyEntity).optimizeRelationships(new LegacyNameGenerator());
+
+        ObjEntity table1Entity = map.getObjEntity("Table1");
+        ObjEntity table2Entity = map.getObjEntity("Table2");
+
+        assertEquals(1, table1Entity.getRelationships().size());
+        assertEquals(table2Entity, new ArrayList<Relationship>(table1Entity.getRelationships()).get(0)
+                .getTargetEntity());
+
+        assertEquals(1, table2Entity.getRelationships().size());
+        assertEquals(table1Entity, new ArrayList<Relationship>(table2Entity.getRelationships()).get(0)
+                .getTargetEntity());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
index f1797f1..8da5038 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java
@@ -81,7 +81,7 @@ public class DbImporterTask extends Task {
         File dataMapFile = config.getDataMapFile();
         config.setFiltersConfig(new FiltersConfigBuilder(reverseEngineering)
                 .add(filterBuilder)
-                .filtersConfig());
+                .build());
 
         validateAttributes();
 
@@ -134,7 +134,7 @@ public class DbImporterTask extends Task {
                             dataMap.setReverseEngineering(reverseEngineering);
 
                             FiltersConfigBuilder filtersConfigBuilder = new FiltersConfigBuilder(dataMap.getReverseEngineering());
-                            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.filtersConfig());
+                            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.build());
                             validateDbImportConfiguration(config, injector);
                             injector.getInstance(DbImportAction.class).execute(config);
                         } catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
index 296a452..ea0f6c7 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
@@ -26,11 +26,11 @@ import org.apache.cayenne.dbsync.merge.DbMergerConfig;
 import org.apache.cayenne.dbsync.merge.DefaultModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
 import org.apache.cayenne.dbsync.merge.ModelMergeDelegate;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
-import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
-import org.apache.cayenne.dbsync.reverse.DbLoaderDelegate;
-import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
-import org.apache.cayenne.dbsync.reverse.LoggingDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.LoggingDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.NameFilter;
 import org.apache.cayenne.dbsync.reverse.NamePatternMatcher;
 import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
index bc6abab..0de47ab 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
@@ -19,7 +19,7 @@
 
 package org.apache.cayenne.tools.dbimport;
 
-import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DefaultDbLoaderDelegate;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.ObjEntity;
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
index 2eeb664..7d17fd7 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
@@ -32,7 +32,7 @@ import org.apache.cayenne.dbsync.merge.MergerToken;
 import org.apache.cayenne.dbsync.merge.ModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.ProxyModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.EntityResolver;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java b/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java
index 5a7c357..45f6478 100644
--- a/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java
+++ b/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java
@@ -33,9 +33,9 @@ import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.MergerToken;
 import org.apache.cayenne.dbsync.merge.builders.DataMapBuilder;
 import org.apache.cayenne.dbsync.merge.factory.DefaultMergerTokenFactory;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
-import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
-import org.apache.cayenne.dbsync.reverse.DbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderDelegate;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.map.DataMap;
@@ -100,11 +100,6 @@ public class DefaultDbImportActionTest {
 			public void load(DataMap dataMap, DbLoaderConfiguration config) throws SQLException {
 				new DataMapBuilder(dataMap).withDbEntities(2).build();
 			}
-
-			@Override
-			public String[] getDefaultTableTypes() {
-				return null;
-			}
 		};
 
         DbImportConfiguration params = mock(DbImportConfiguration.class);
@@ -150,11 +145,6 @@ public class DefaultDbImportActionTest {
                                 objAttr("name").type(String.class).dbPath("NAME")
                         ));
             }
-
-			@Override
-			public String[] getDefaultTableTypes() {
-				return null;
-			}
 		};
 
         DbImportConfiguration params = mock(DbImportConfiguration.class);
@@ -213,11 +203,6 @@ public class DefaultDbImportActionTest {
                                 dbAttr("NAME").typeVarchar(100).mandatory()
                         ));
             }
-
-			@Override
-			public String[] getDefaultTableTypes() {
-				return null;
-			}
 		};
 
         DbImportConfiguration params = mock(DbImportConfiguration.class);
@@ -253,7 +238,6 @@ public class DefaultDbImportActionTest {
 	@Test
 	public void testImportWithDbError() throws Exception {
 		DbLoader dbLoader = mock(DbLoader.class);
-		when(dbLoader.getDefaultTableTypes()).thenReturn(null);
 		doThrow(new SQLException()).when(dbLoader).load(any(DataMap.class), any(DbLoaderConfiguration.class));
 
         DbImportConfiguration params = mock(DbImportConfiguration.class);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
index 6a665fe..b8e7383 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
@@ -21,7 +21,7 @@ package org.apache.cayenne.modeler.action;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.DataSourceController;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
index 35f4cb1..a9016c8 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
@@ -24,8 +24,8 @@ import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbimport.ReverseEngineering;
 import org.apache.cayenne.dbsync.CayenneDbSyncModule;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
-import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DefaultDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.FiltersConfigBuilder;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
@@ -359,7 +359,7 @@ public class DbLoaderHelper {
             }
 
             FiltersConfigBuilder filtersConfigBuilder = new FiltersConfigBuilder(reverseEngineering);
-            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.filtersConfig());
+            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.build());
 
 
             ModelerDbImportAction importAction = new ModelerDbImportAction(logObj, DbLoaderHelper.this);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
index 0d07706..b8e2a08 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
@@ -30,7 +30,7 @@ import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.MergerToken;
 import org.apache.cayenne.dbsync.merge.ModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
 import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
 import org.apache.cayenne.dbsync.reverse.filters.TableFilter;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
index 15d15b0..6ca30af 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
@@ -18,9 +18,9 @@
  ****************************************************************/
 package org.apache.cayenne.modeler.dialog.db;
 
-import org.apache.cayenne.dbsync.reverse.DbLoader;
-import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
-import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.db.DefaultDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
 import org.apache.cayenne.dbsync.reverse.filters.SchemaFilter;
 import org.apache.cayenne.map.DataMap;
@@ -70,10 +70,8 @@ class ModelerDbLoader extends DbLoader {
     public void load(DataMap dataMap, DbLoaderConfiguration config) throws SQLException {
         LOGGER.info("Schema loading...");
 
-        String[] types = config.getTableTypes();
-        if (types == null || types.length == 0) {
-            types = getDefaultTableTypes();
-        }
+        String[] types = getTableTypes(config);
+
         boolean isNullDetected = false;
         for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
             for (SchemaFilter schema : catalog.schemas) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
index da5dc7a..4e1172b 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
@@ -20,8 +20,8 @@ package org.apache.cayenne.modeler.dialog.db;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbimport.ReverseEngineering;
-import org.apache.cayenne.dbsync.reverse.DbLoader;
-import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
 import org.apache.cayenne.dbsync.reverse.FiltersConfigBuilder;
 import org.apache.cayenne.modeler.ClassLoadingService;
 import org.apache.cayenne.modeler.ProjectController;
@@ -107,7 +107,7 @@ public class ReverseEngineeringController extends CayenneController {
 
             FiltersConfigBuilder filtersConfigBuilder = new FiltersConfigBuilder(reverseEngineering);
             DbLoaderConfiguration dbLoaderConfiguration = new DbLoaderConfiguration();
-            dbLoaderConfiguration.setFiltersConfig(filtersConfigBuilder.filtersConfig());
+            dbLoaderConfiguration.setFiltersConfig(filtersConfigBuilder.build());
 
             try(Connection connection = dataSource.getConnection()) {
                 DbLoader dbLoader = new ModelerDbLoader(this, treeEditor, connection);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cf172fc9/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java b/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
index 7c8872b..c96e904 100644
--- a/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
+++ b/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java
@@ -319,7 +319,7 @@ public class DbImporterMojo extends AbstractMojo {
                             dataMap.setReverseEngineering(reverseEngineering);
 
                             FiltersConfigBuilder filtersConfigBuilder = new FiltersConfigBuilder(dataMap.getReverseEngineering());
-                            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.filtersConfig());
+                            config.getDbLoaderConfig().setFiltersConfig(filtersConfigBuilder.build());
                             validateDbImportConfiguration(config, injector);
                             injector.getInstance(DbImportAction.class).execute(config);
                         } catch (Exception ex) {
@@ -382,7 +382,7 @@ public class DbImporterMojo extends AbstractMojo {
         config.setUsername(username);
         config.setUsePrimitives(usePrimitives);
         config.setFiltersConfig(new FiltersConfigBuilder(reverseEngineering)
-                .add(filterBuilder).filtersConfig());
+                .add(filterBuilder).build());
         config.setSkipRelationshipsLoading(reverseEngineering.getSkipRelationshipsLoading());
         config.setSkipPrimaryKeyLoading(reverseEngineering.getSkipPrimaryKeyLoading());
         config.setTableTypes(reverseEngineering.getTableTypes());