package org.hibernate.tool.test.jdbc2cfg;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.JDBCMetaDataConfiguration;
import org.hibernate.cfg.reveng.TableIdentifier;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
import org.hibernate.tool.hbm2x.Exporter;
import org.hibernate.tool.hbm2x.HibernateMappingExporter;
import org.hibernate.tool.hbm2x.POJOExporter;
import org.hibernate.tools.test.util.HibernateUtil;
import org.hibernate.tools.test.util.JavaUtil;
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;
public class KeyPropertyCompositeIdTest {
static final String[] CREATE_SQL = new String[] {
"CREATE TABLE CUSTOMER (CUSTOMER_ID VARCHAR(256) NOT NULL, NAME VARCHAR(256) NOT NULL, ADDRESS VARCHAR(256) NOT NULL, PRIMARY KEY (CUSTOMER_ID))",
"CREATE TABLE PRODUCT (PRODUCT_ID VARCHAR(256) NOT NULL, EXTRA_ID VARCHAR(256) NOT NULL, DESCRIPTION VARCHAR(256) NOT NULL, PRICE FLOAT, NUMBER_AVAILABLE FLOAT, PRIMARY KEY (PRODUCT_ID, EXTRA_ID))",
"CREATE TABLE SIMPLE_CUSTOMER_ORDER (CUSTOMER_ORDER_ID VARCHAR(256) NOT NULL, CUSTOMER_ID VARCHAR(256) NOT NULL, ORDER_NUMBER FLOAT NOT NULL, ORDER_DATE DATE, PRIMARY KEY (CUSTOMER_ORDER_ID), FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMER(CUSTOMER_ID))",
"CREATE TABLE SIMPLE_LINE_ITEM ( LINE_ITEM_ID VARCHAR(256) NOT NULL, CUSTOMER_ORDER_ID_REF VARCHAR(256), PRODUCT_ID VARCHAR(256) NOT NULL, EXTRA_ID VARCHAR(256) NOT NULL, QUANTITY FLOAT, PRIMARY KEY (LINE_ITEM_ID), FOREIGN KEY (PRODUCT_ID,EXTRA_ID) REFERENCES PRODUCT(PRODUCT_ID,EXTRA_ID), FOREIGN KEY (CUSTOMER_ORDER_ID_REF) REFERENCES SIMPLE_CUSTOMER_ORDER(CUSTOMER_ORDER_ID))",
"CREATE TABLE CUSTOMER_ORDER (CUSTOMER_ID VARCHAR(256) NOT NULL, ORDER_NUMBER FLOAT NOT NULL, ORDER_DATE DATE, PRIMARY KEY (CUSTOMER_ID, ORDER_NUMBER), FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMER(CUSTOMER_ID))",
"CREATE TABLE LINE_ITEM (CUSTOMER_ID_REF VARCHAR(256) NOT NULL, ORDER_NUMBER FLOAT NOT NULL, PRODUCT_ID VARCHAR(256) NOT NULL, EXTRA_PROD_ID VARCHAR(256) NOT NULL, QUANTITY FLOAT, PRIMARY KEY (CUSTOMER_ID_REF, ORDER_NUMBER, PRODUCT_ID, EXTRA_PROD_ID), FOREIGN KEY (PRODUCT_ID,EXTRA_PROD_ID) REFERENCES PRODUCT(PRODUCT_ID,EXTRA_ID), CONSTRAINT TO_CUSTOMER_ORDER FOREIGN KEY (CUSTOMER_ID_REF, ORDER_NUMBER) REFERENCES CUSTOMER_ORDER(CUSTOMER_ID,ORDER_NUMBER))"
};
static final String[] DATA_SQL = new String[] {
"INSERT INTO PRODUCT (PRODUCT_ID, EXTRA_ID, DESCRIPTION, PRICE, NUMBER_AVAILABLE) VALUES('PC', '0', 'My PC', 100.0, 23)",
"INSERT INTO PRODUCT (PRODUCT_ID, EXTRA_ID, DESCRIPTION, PRICE, NUMBER_AVAILABLE) VALUES('MS', '1', 'My Mouse', 101.0, 23)",
"INSERT INTO CUSTOMER (CUSTOMER_ID, NAME, ADDRESS) VALUES('MAX', 'Max Rydahl Andersen', 'Neuchatel')",
"INSERT INTO CUSTOMER_ORDER (CUSTOMER_ID, ORDER_NUMBER, ORDER_DATE) VALUES ('MAX', 1, null)",
"INSERT INTO LINE_ITEM (CUSTOMER_ID_REF, ORDER_NUMBER, PRODUCT_ID, EXTRA_PROD_ID, QUANTITY) VALUES ('MAX', 1, 'PC', '0', 10)",
"INSERT INTO LINE_ITEM (CUSTOMER_ID_REF, ORDER_NUMBER, PRODUCT_ID, EXTRA_PROD_ID, QUANTITY) VALUES ('MAX', 1, 'MS', '1', 12)",
};
static final String[] DROP_SQL = new String[] {
"DROP TABLE LINE_ITEM ",
"DROP TABLE CUSTOMER_ORDER ",
"DROP TABLE SIMPLE_LINE_ITEM ",
"DROP TABLE SIMPLE_CUSTOMER_ORDER ",
"DROP TABLE PRODUCT ",
"DROP TABLE CUSTOMER ",
};
private JDBCMetaDataConfiguration jmdcfg = null;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
public void setUp() {
JdbcUtil.createDatabase(this);;
jmdcfg = new JDBCMetaDataConfiguration();
jmdcfg.setPreferBasicCompositeIds(false);
jmdcfg.readFromJDBC();
}
@After
public void tearDown() {
JdbcUtil.dropDatabase(this);;
}
@Test
public void testMultiColumnForeignKeys() {
Table table = jmdcfg.getTable(JdbcUtil.toIdentifier(this, "LINE_ITEM"));
Assert.assertNotNull(table);
ForeignKey foreignKey = HibernateUtil.getForeignKey(table, JdbcUtil.toIdentifier(this, "TO_CUSTOMER_ORDER"));
Assert.assertNotNull(foreignKey);
Assert.assertEquals(
jmdcfg.getReverseEngineeringStrategy().tableToClassName(
new TableIdentifier(null, null, JdbcUtil.toIdentifier(this, "CUSTOMER_ORDER"))),
foreignKey.getReferencedEntityName());
Assert.assertEquals(JdbcUtil.toIdentifier(this, "LINE_ITEM"), foreignKey.getTable().getName());
Assert.assertEquals(2, foreignKey.getColumnSpan());
Assert.assertEquals(foreignKey.getColumn(0).getName(), "CUSTOMER_ID_REF");
Assert.assertEquals(foreignKey.getColumn(1).getName(), "ORDER_NUMBER");
Table tab = jmdcfg.getTable(JdbcUtil.toIdentifier(this, "CUSTOMER_ORDER"));
Assert.assertEquals(tab.getPrimaryKey().getColumn(0).getName(), "CUSTOMER_ID");
Assert.assertEquals(tab.getPrimaryKey().getColumn(1).getName(), "ORDER_NUMBER");
PersistentClass lineMapping = jmdcfg.getMetadata().getEntityBinding(jmdcfg.getReverseEngineeringStrategy()
.tableToClassName(new TableIdentifier(null, null, JdbcUtil.toIdentifier(this, "LINE_ITEM"))));
Assert.assertEquals(4, lineMapping.getIdentifier().getColumnSpan());
Iterator<?> columnIterator = lineMapping.getIdentifier().getColumnIterator();
Assert.assertEquals(((Column) (columnIterator.next())).getName(), "CUSTOMER_ID_REF");
Assert.assertEquals(((Column) (columnIterator.next())).getName(), "ORDER_NUMBER");
}
@Test
public void testPossibleKeyManyToOne() {
PersistentClass product = jmdcfg.getMetadata().getEntityBinding(jmdcfg.getReverseEngineeringStrategy()
.tableToClassName(new TableIdentifier(null, null, JdbcUtil.toIdentifier(this, "CUSTOMER_ORDER"))));
Property identifierProperty = product.getIdentifierProperty();
Assert.assertTrue(identifierProperty.getValue() instanceof Component);
Component cmpid = (Component) identifierProperty.getValue();
Assert.assertEquals(2, cmpid.getPropertySpan());
Iterator<?> iter = cmpid.getPropertyIterator();
Property id = (Property) iter.next();
Property extraId = (Property) iter.next();
Assert.assertEquals(
jmdcfg.getReverseEngineeringStrategy().columnToPropertyName(
null,
"customer"),
id.getName());
Assert.assertEquals(
jmdcfg.getReverseEngineeringStrategy().columnToPropertyName(
null,
"orderNumber"),
extraId.getName());
Assert.assertTrue(id.getValue() instanceof ManyToOne);
Assert.assertFalse(extraId.getValue() instanceof ManyToOne);
}
@Test
public void testKeyProperty() {
PersistentClass product = jmdcfg.getMetadata().getEntityBinding(jmdcfg.getReverseEngineeringStrategy()
.tableToClassName(new TableIdentifier(null, null, JdbcUtil.toIdentifier(this, "PRODUCT"))));
Property identifierProperty = product.getIdentifierProperty();
Assert.assertTrue(identifierProperty.getValue() instanceof Component);
Component cmpid = (Component) identifierProperty.getValue();
Assert.assertEquals(2, cmpid.getPropertySpan());
Iterator<?> iter = cmpid.getPropertyIterator();
Property id = (Property) iter.next();
Property extraId = (Property) iter.next();
Assert.assertEquals(
jmdcfg.getReverseEngineeringStrategy().columnToPropertyName(
null,
"productId"),
id.getName());
Assert.assertEquals(
jmdcfg.getReverseEngineeringStrategy().columnToPropertyName(
null,
"extraId"),
extraId.getName());
Assert.assertFalse(id.getValue() instanceof ManyToOne);
Assert.assertFalse(extraId.getValue() instanceof ManyToOne);
}
@Test
public void testGeneration() throws Exception {
final File testFolder = temporaryFolder.getRoot();
Exporter exporter = new HibernateMappingExporter(jmdcfg, testFolder);
Exporter javaExp = new POJOExporter(jmdcfg, testFolder);
exporter.start();
javaExp.start();
JavaUtil.compile(testFolder);
URL[] urls = new URL[] { testFolder.toURI().toURL() };
URLClassLoader ucl = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().applyClassLoader(ucl)
.build();
Configuration derived = new Configuration(bootstrapServiceRegistry);
derived.addFile(new File(testFolder, "Simplecustomerorder.hbm.xml"));
derived.addFile(new File(testFolder, "Simplelineitem.hbm.xml"));
derived.addFile(new File(testFolder, "Product.hbm.xml"));
derived.addFile(new File(testFolder, "Customer.hbm.xml"));
derived.addFile(new File(testFolder, "Lineitem.hbm.xml"));
derived.addFile(new File(testFolder, "Customerorder.hbm.xml"));
Thread.currentThread().setContextClassLoader(ucl);
SessionFactory factory = derived.buildSessionFactory();
Session session = factory.openSession();
JdbcUtil.populateDatabase(this);;
session.createQuery("from LineItem").getResultList();
List<?> list = session.createQuery("from Product").getResultList();
Assert.assertEquals(2, list.size());
list = session
.createQuery("select li.id.customerOrder.id from LineItem as li")
.getResultList();
Assert.assertTrue(list.size() > 0);
Class<?> productIdClass = ucl.loadClass("ProductId");
Object object = productIdClass.newInstance();
int hash = -1;
try {
hash = object.hashCode();
} catch (Throwable t) {
Assert.fail("Hashcode on new instance should not fail " + t);
}
Assert.assertFalse("hashcode should be different from system", hash == System.identityHashCode(object));
factory.close();
Thread.currentThread().setContextClassLoader(ucl.getParent());
}
}