/* * Created on 2004-12-01 * */ package org.hibernate.tool.test.jdbc2cfg; import java.io.File; import org.hibernate.MappingException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.JDBCMetaDataConfiguration; import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy; import org.hibernate.cfg.reveng.ReverseEngineeringSettings; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.tool.hbm2x.HibernateMappingExporter; import org.hibernate.tool.util.MetadataHelper; import org.hibernate.tools.test.util.JdbcUtil; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; /** * @author max * @author koen * */ public class ManyToManyTest { static final String[] CREATE_SQL = new String[] { "CREATE TABLE PROJECT (PROJECT_ID INTEGER NOT NULL, NAME VARCHAR(50), PRIMARY KEY (PROJECT_ID) )", "CREATE TABLE EMPLOYEE (ID INTEGER NOT NULL, NAME VARCHAR(50), MANAGER_ID INTEGER, PRIMARY KEY (ID), CONSTRAINT EMPLOYEE_MANAGER FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEE(ID))", "CREATE TABLE WORKS_ON (PROJECT_ID INTEGER NOT NULL, EMPLOYEE_ID INTEGER NOT NULL, PRIMARY KEY (PROJECT_ID, EMPLOYEE_ID), CONSTRAINT WORKSON_EMPLOYEE FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEE(ID), FOREIGN KEY (PROJECT_ID) REFERENCES PROJECT(PROJECT_ID) )", "CREATE TABLE WORKS_ON_CONTEXT (PROJECT_ID INTEGER NOT NULL, EMPLOYEE_ID INTEGER NOT NULL, CREATED_BY INTEGER, PRIMARY KEY (PROJECT_ID, EMPLOYEE_ID), CONSTRAINT WORKSON_CTX_EMPLOYEE FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEE(ID), FOREIGN KEY (PROJECT_ID) REFERENCES PROJECT(PROJECT_ID), FOREIGN KEY (CREATED_BY) REFERENCES EMPLOYEE(ID) )", //"alter table PROJECT add constraint project_manager foreign key (team_lead) references EMPLOYEE" // nonmiddle left and right are used to test a false association table isn't detected. "CREATE TABLE LEFT_TABLE ( id INTEGER NOT NULL, PRIMARY KEY (ID) )", "CREATE TABLE RIGHT_TABLE ( id INTEGER NOT NULL, PRIMARY KEY (ID) )", "CREATE TABLE NON_MIDDLE ( left_id INTEGER NOT NULL, RIGHT_ID INTEGER NOT NULL, PRIMARY KEY (LEFT_ID), CONSTRAINT FK_MIDDLE_LEFT FOREIGN KEY (LEFT_ID) REFERENCES LEFT_TABLE(ID), CONSTRAINT FK_MIDDLE_RIGHT FOREIGN KEY (RIGHT_ID) REFERENCES RIGHT_TABLE(ID))", }; static final String[] DROP_SQL = new String[] { //"alter table PROJECT drop constraint project_manager", "DROP TABLE WORKS_ON_CONTEXT", "DROP TABLE WORKS_ON", "DROP TABLE EMPLOYEE", "DROP TABLE PROJECT", "DROP TABLE NON_MIDDLE", "DROP TABLE LEFT_TABLE", "DROP TABLE RIGHT_TABLE", }; private JDBCMetaDataConfiguration jmdcfg = null; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before public void setUp() { JdbcUtil.createDatabase(this); jmdcfg = new JDBCMetaDataConfiguration(); jmdcfg.readFromJDBC(); } @After public void tearDown() { JdbcUtil.dropDatabase(this); } @Test public void testNoManyToManyBiDirectional() { JDBCMetaDataConfiguration localCfg = new JDBCMetaDataConfiguration(); DefaultReverseEngineeringStrategy c = new DefaultReverseEngineeringStrategy(); c.setSettings(new ReverseEngineeringSettings(c).setDetectManyToMany(false)); localCfg.setReverseEngineeringStrategy(c); localCfg.readFromJDBC(); PersistentClass project = localCfg.getMetadata().getEntityBinding("Project"); Assert.assertNotNull(project.getProperty("worksOns")); //assertNotNull(project.getProperty("employee")); Assert.assertEquals(3, project.getPropertyClosureSpan()); Assert.assertEquals("projectId", project.getIdentifierProperty().getName()); PersistentClass employee = localCfg.getMetadata().getEntityBinding("Employee"); Assert.assertNotNull(employee.getProperty("worksOns")); Assert.assertNotNull(employee.getProperty("employees")); Assert.assertNotNull(employee.getProperty("employee")); //assertNotNull(employee.getProperty("projects")); Assert.assertEquals(6, employee.getPropertyClosureSpan()); Assert.assertEquals("id", employee.getIdentifierProperty().getName()); PersistentClass worksOn = localCfg.getMetadata().getEntityBinding("WorksOn"); Assert.assertNotNull(worksOn.getProperty("project")); Assert.assertNotNull(worksOn.getProperty("employee")); Assert.assertEquals(2, worksOn.getPropertyClosureSpan()); Assert.assertEquals("id", worksOn.getIdentifierProperty().getName()); } @Test public void testAutoCreation() { Assert.assertNull("No middle class should be generated.", jmdcfg.getMetadata().getEntityBinding( "WorksOn" )); Assert.assertNotNull("Should create worksontext since one of the foreign keys is not part of pk", jmdcfg.getMetadata().getEntityBinding( "WorksOnContext" )); PersistentClass projectClass = jmdcfg.getMetadata().getEntityBinding("Project"); Assert.assertNotNull( projectClass ); PersistentClass employeeClass = jmdcfg.getMetadata().getEntityBinding("Employee"); Assert.assertNotNull( employeeClass ); assertPropertyNotExist( projectClass, "worksOns" ); assertPropertyNotExist( employeeClass, "worksOns" ); Property property = employeeClass.getProperty( "projects" ); Assert.assertNotNull( property); Assert.assertNotNull( projectClass.getProperty( "employees" )); } @Test public void testFalsePositive() { Assert.assertNotNull("Middle class should be generated.", jmdcfg.getMetadata().getEntityBinding( "NonMiddle" )); } @Test public void testBuildMappings() { Assert.assertNotNull(MetadataHelper.getMetadata(jmdcfg)); } @Test public void testGenerateAndReadable() { File outputDir = temporaryFolder.getRoot(); Assert.assertNotNull(MetadataHelper.getMetadata(jmdcfg)); HibernateMappingExporter hme = new HibernateMappingExporter(jmdcfg, outputDir); hme.start(); assertFileAndExists( new File(outputDir, "Employee.hbm.xml") ); assertFileAndExists( new File(outputDir, "Project.hbm.xml") ); assertFileAndExists( new File(outputDir, "WorksOnContext.hbm.xml") ); assertFileAndExists( new File(outputDir, "RightTable.hbm.xml") ); assertFileAndExists( new File(outputDir, "LeftTable.hbm.xml") ); assertFileAndExists( new File(outputDir, "NonMiddle.hbm.xml") ); //Must be there since it has a fkey that is not part of the pk Assert.assertFalse(new File(outputDir, "WorksOn.hbm.xml").exists() ); Assert.assertEquals(6, outputDir.listFiles().length); Configuration configuration = new Configuration() .addFile( new File(outputDir, "Employee.hbm.xml") ) .addFile( new File(outputDir, "Project.hbm.xml") ) .addFile( new File(outputDir, "WorksOnContext.hbm.xml") ); Assert.assertNotNull(MetadataHelper.getMetadata(configuration)); } private void assertPropertyNotExist(PersistentClass projectClass, String prop) { try { projectClass.getProperty(prop); Assert.fail("property " + prop + " should not exist on " + projectClass); } catch(MappingException e) { // expected } } private void assertFileAndExists(File file) { Assert.assertTrue(file + " does not exist", file.exists() ); Assert.assertTrue(file + " not a file", file.isFile() ); Assert.assertTrue(file + " does not have any contents", file.length()>0); } protected String[] getCreateSQL() { return new String[] { "create table PROJECT ( project_id integer not null, name varchar(50), primary key (project_id) )", "create table EMPLOYEE ( id integer not null, name varchar(50), manager_id integer, primary key (id), constraint employee_manager foreign key (manager_id) references EMPLOYEE(id))", "create table WORKS_ON ( project_id integer not null, employee_id integer not null, primary key (project_id, employee_id), constraint workson_employee foreign key (employee_id) references EMPLOYEE(id), foreign key (project_id) references PROJECT(project_id) )", "create table WORKS_ON_CONTEXT ( project_id integer not null, employee_id integer not null, created_by integer, primary key (project_id, employee_id), constraint workson_ctx_employee foreign key (employee_id) references EMPLOYEE, foreign key (project_id) references PROJECT(project_id), foreign key (created_by) references EMPLOYEE(id) )", //"alter table PROJECT add constraint project_manager foreign key (team_lead) references EMPLOYEE" // nonmiddle left and right are used to test a false association table isn't detected. "create table LEFT_TABLE ( id integer not null, primary key (id) )", "create table RIGHT_TABLE ( id integer not null, primary key (id) )", "create table NON_MIDDLE ( left_id integer not null, right_id integer not null, primary key (left_id), constraint FK_MIDDLE_LEFT foreign key (left_id) references LEFT_TABLE(id), constraint FK_MIDDLE_RIGHT foreign key (right_id) references RIGHT_TABLE(id))", }; } protected String[] getDropSQL() { return new String[] { //"alter table PROJECT drop constraint project_manager", "drop table WORKS_ON_CONTEXT", "drop table WORKS_ON", "drop table EMPLOYEE", "drop table PROJECT", "drop table NON_MIDDLE", "drop table LEFT_TABLE", "drop table RIGHT_TABLE", }; } }