/*
* Created on 2004-12-01
*
*/
package org.hibernate.tool.test.jdbc2cfg;
import java.net.MalformedURLException;
import org.hibernate.MappingException;
import org.hibernate.cfg.JDBCMetaDataConfiguration;
import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.OverrideRepository;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.tool.JDBCMetaDataBinderTestCase;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* @author max
*
*/
public class RevEngForeignKeyTests extends JDBCMetaDataBinderTestCase {
private static final String FOREIGN_KEY_TEST_XML = "org/hibernate/tool/test/jdbc2cfg/foreignkeytest.reveng.xml";
private static final String BAD_FOREIGNKEY_XML = "org/hibernate/tool/test/jdbc2cfg/badforeignkeytest.reveng.xml";;
public static Test suite() {
return new TestSuite(RevEngForeignKeyTests.class);
}
public void testDefaultBiDirectional() {
PersistentClass project = cfg.getMetadata().getEntityBinding("Project");
assertNotNull(project.getProperty("worksOns"));
assertNotNull(project.getProperty("employee"));
assertEquals(3, project.getPropertyClosureSpan());
assertEquals("projectId", project.getIdentifierProperty().getName());
PersistentClass employee = cfg.getMetadata().getEntityBinding("Employee");
assertNotNull(employee.getProperty("worksOns"));
assertNotNull(employee.getProperty("employees"));
assertNotNull(employee.getProperty("employee"));
assertNotNull(employee.getProperty("projects"));
assertEquals(5, employee.getPropertyClosureSpan());
assertEquals("id", employee.getIdentifierProperty().getName());
PersistentClass worksOn = cfg.getMetadata().getEntityBinding("WorksOn");
assertNotNull(worksOn.getProperty("project"));
assertNotNull(worksOn.getProperty("employee"));
assertEquals(4, worksOn.getPropertyClosureSpan());
assertEquals("id", worksOn.getIdentifierProperty().getName());
}
public void testSetAndManyToOne() {
OverrideRepository or = buildOverrideRepository();
or.addResource(FOREIGN_KEY_TEST_XML);
ReverseEngineeringStrategy repository = or.getReverseEngineeringStrategy(new DefaultReverseEngineeringStrategy());
JDBCMetaDataConfiguration localCfg = new JDBCMetaDataConfiguration();
localCfg.setReverseEngineeringStrategy(repository);
localCfg.readFromJDBC();
PersistentClass project = localCfg.getMetadata().getEntityBinding("Project");
assertNotNull(project.getProperty("worksOns"));
assertPropertyNotExists(project, "employee", "should be removed by reveng.xml");
Property property = project.getProperty("teamLead");
assertNotNull(property);
assertTrue(property.getValue() instanceof SimpleValue);
assertEquals(3, project.getPropertyClosureSpan());
assertEquals("projectId", project.getIdentifierProperty().getName());
PersistentClass employee = localCfg.getMetadata().getEntityBinding("Employee");
assertNotNull(employee.getProperty("worksOns"));
assertNotNull("property should be renamed by reveng.xml", employee.getProperty("manager"));
assertPropertyNotExists( employee, "employees", "set should be excluded by reveng.xml" );
Property setProperty = employee.getProperty("managedProjects");
assertNotNull("should be renamed by reveng.xml", setProperty);
assertEquals("delete, update", setProperty.getCascade());
assertEquals(4, employee.getPropertyClosureSpan());
assertEquals("id", employee.getIdentifierProperty().getName());
PersistentClass worksOn = localCfg.getMetadata().getEntityBinding("WorksOn");
assertNotNull(worksOn.getProperty("project"));
assertNotNull(worksOn.getProperty("employee"));
assertEquals(4, worksOn.getPropertyClosureSpan());
assertEquals("id", worksOn.getIdentifierProperty().getName());
}
public void testOneToOne() throws MalformedURLException, ClassNotFoundException {
OverrideRepository or = buildOverrideRepository();
or.addResource(FOREIGN_KEY_TEST_XML);
ReverseEngineeringStrategy repository = or.getReverseEngineeringStrategy(new DefaultReverseEngineeringStrategy());
JDBCMetaDataConfiguration localCfg = new JDBCMetaDataConfiguration();
localCfg.setReverseEngineeringStrategy(repository);
localCfg.readFromJDBC();
PersistentClass person = localCfg.getMetadata().getEntityBinding("Person");
PersistentClass addressPerson = localCfg.getMetadata().getEntityBinding("AddressPerson");
PersistentClass addressMultiPerson = localCfg.getMetadata().getEntityBinding("AddressMultiPerson");
PersistentClass multiPerson = localCfg.getMetadata().getEntityBinding("MultiPerson");
assertPropertyNotExists(addressPerson, "person", "should be removed by reveng.xml");
assertPropertyNotExists(person, "addressPerson", "should be removed by reveng.xml");
Property property = addressMultiPerson.getProperty("renamedOne");
assertNotNull(property);
assertEquals("Casade should be set to delete by reveng.xml", "delete", property.getCascade());
assertPropertyNotExists(multiPerson, "addressMultiPerson", "should not be there");
Property o2o = multiPerson.getProperty("renamedInversedOne");
assertNotNull(o2o);
assertEquals("update", o2o.getCascade());
assertEquals("JOIN", o2o.getValue().getFetchMode().toString());
}
public void testDuplicateForeignKeyDefinition() {
OverrideRepository or = buildOverrideRepository();
or.addResource(BAD_FOREIGNKEY_XML);
ReverseEngineeringStrategy repository = or.getReverseEngineeringStrategy(new DefaultReverseEngineeringStrategy());
JDBCMetaDataConfiguration localCfg = new JDBCMetaDataConfiguration();
localCfg.setReverseEngineeringStrategy(repository);
try {
localCfg.readFromJDBC();
fail("Should fail because foreign key is already defined in the database"); // maybe we should ignore the definition and only listen to what is overwritten ? For now we error.
} catch(MappingException me) {
assertTrue(me.getMessage().indexOf("already defined")>=0);
}
}
public void testManyToOneAttributeDefaults() {
PersistentClass classMapping = cfg.getMetadata().getEntityBinding("Employee");
Property property = classMapping.getProperty("employee");
assertEquals("none", property.getCascade());
assertEquals(true, property.isUpdateable());
assertEquals(true, property.isInsertable());
assertEquals("SELECT", property.getValue().getFetchMode().toString());
}
public void testManyToOneAttributeOverrides() {
OverrideRepository or = buildOverrideRepository();
or.addResource(FOREIGN_KEY_TEST_XML);
ReverseEngineeringStrategy repository = or.getReverseEngineeringStrategy(new DefaultReverseEngineeringStrategy());
JDBCMetaDataConfiguration localCfg = new JDBCMetaDataConfiguration();
localCfg.setReverseEngineeringStrategy(repository);
localCfg.readFromJDBC();
PersistentClass classMapping = localCfg.getMetadata().getEntityBinding("Employee");
Property property = classMapping.getProperty("manager");
assertEquals("all", property.getCascade());
assertEquals(false, property.isUpdateable());
assertEquals(false, property.isInsertable());
assertEquals("JOIN", property.getValue().getFetchMode().toString());
}
private void assertPropertyNotExists(PersistentClass employee, String name, String msg) {
try {
employee.getProperty(name);
fail(msg);
} catch(MappingException me) {
// excpected
}
}
private OverrideRepository buildOverrideRepository() {
return new OverrideRepository();
}
protected String[] getCreateSQL() {
return new String[] {
"create table PROJECT ( project_id integer not null, name varchar(50), team_lead integer, 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)",
"create table WORKS_ON ( project_id integer not null, employee_id integer not null, start_date date, end_date date, primary key (project_id, employee_id), constraint workson_employee foreign key (employee_id) references EMPLOYEE, foreign key (project_id) references PROJECT )",
"create table PERSON ( person_id integer not null, name varchar(50), primary key (person_id) )",
"create table ADDRESS_PERSON ( address_id integer not null, name varchar(50), primary key (address_id), constraint address_person foreign key (address_id) references PERSON)",
"create table MULTI_PERSON ( person_id integer not null, person_compid integer not null, name varchar(50), primary key (person_id, person_compid) )",
"create table ADDRESS_MULTI_PERSON ( address_id integer not null, address_compid integer not null, name varchar(50), primary key (address_id, address_compid), constraint address_multi_person foreign key (address_id, address_compid) references MULTI_PERSON)",
"alter table PROJECT add constraint project_manager foreign key (team_lead) references EMPLOYEE"
};
}
protected String[] getDropSQL() {
return new String[] {
"alter table PROJECT drop constraint project_manager",
"drop table WORKS_ON",
"drop table EMPLOYEE",
"drop table PROJECT",
"drop table ADDRESS_PERSON",
"drop table PERSON",
"drop table ADDRESS_MULTI_PERSON",
"drop table MULTI_PERSON"
};
}
}