use of com.manydesigns.portofino.model.database.Table in project Portofino by ManyDesigns.
the class SessionFactoryBuilder method configureAnnotations.
protected void configureAnnotations(Table table, ConstPool constPool, AnnotationsAttribute classAnnotations) {
Annotation annotation;
annotation = new Annotation(javax.persistence.Table.class.getName(), constPool);
annotation.addMemberValue("name", new StringMemberValue(jpaEscape(table.getTableName()), constPool));
if (multiTenancyImplementation == null || multiTenancyImplementation.getStrategy() != MultiTenancyStrategy.SCHEMA) {
// Don't configure the schema name if we're using schema-based multitenancy
String schemaName = table.getSchema().getActualSchemaName();
annotation.addMemberValue("schema", new StringMemberValue(jpaEscape(schemaName), constPool));
}
classAnnotations.addAnnotation(annotation);
annotation = new Annotation(Entity.class.getName(), constPool);
annotation.addMemberValue("name", new StringMemberValue(table.getActualEntityName(), constPool));
classAnnotations.addAnnotation(annotation);
table.getAnnotations().forEach(ann -> {
Class annotationClass = ann.getJavaAnnotationClass();
if (javax.persistence.Table.class.equals(annotationClass) || Entity.class.equals(annotationClass)) {
logger.warn("@Table or @Entity specified on table {}, skipping annotation {}", table.getQualifiedName(), annotationClass);
return;
}
Annotation classAnn = convertAnnotation(constPool, ann);
if (classAnn != null) {
classAnnotations.addAnnotation(classAnn);
}
if (annotationClass == Updatable.class && !((Updatable) ann.getJavaAnnotation()).value()) {
classAnnotations.addAnnotation(new Annotation(Immutable.class.getName(), constPool));
}
});
}
use of com.manydesigns.portofino.model.database.Table in project Portofino by ManyDesigns.
the class SessionFactoryBuilder method checkValidFk.
protected boolean checkValidFk(ForeignKey foreignKey) {
Table toTable = foreignKey.getToTable();
if (toTable == null) {
logger.error("The foreign key " + foreignKey.getQualifiedName() + " does not refer to any table.");
return false;
}
if (checkInvalidPrimaryKey(toTable, false)) {
logger.error("The foreign key " + foreignKey.getQualifiedName() + " refers to a table with absent or invalid primary key.");
return false;
}
// Check that referenced columns coincide with the primary key
Set<Column> fkColumns = new HashSet<>();
Set<Column> pkColumns = new HashSet<>(toTable.getPrimaryKey().getColumns());
for (Reference reference : foreignKey.getReferences()) {
fkColumns.add(reference.getActualToColumn());
}
if (!fkColumns.equals(pkColumns)) {
logger.error("The foreign key " + foreignKey.getQualifiedName() + " does not refer to " + "the exact primary key of table " + toTable.getQualifiedName() + ", this is not supported.");
return false;
}
try {
getMappedClass(toTable);
} catch (NotFoundException e) {
logger.error("The foreign key " + foreignKey.getQualifiedName() + " refers to unmapped table " + toTable.getQualifiedName() + ", skipping.");
return false;
}
return true;
}
use of com.manydesigns.portofino.model.database.Table in project Portofino by ManyDesigns.
the class SessionFactoryBuilder method buildSessionFactory.
public SessionFactoryAndCodeBase buildSessionFactory(FileObject root) throws Exception {
List<Table> mappableTables = database.getAllTables();
mappableTables.removeIf(this::checkInvalidPrimaryKey);
List<Table> externallyMappedTables = mappableTables.stream().filter(t -> {
boolean externallyMapped = t.getActualJavaClass() != null;
if (externallyMapped) {
logger.debug("Skipping table explicitly mapped with {}", t.getActualJavaClass());
}
return externallyMapped;
}).collect(Collectors.toList());
mappableTables.removeAll(externallyMappedTables);
// Use a new classloader as scratch space for Javassist
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader scratchClassLoader = new URLClassLoader(new URL[0], contextClassLoader);
Thread.currentThread().setContextClassLoader(scratchClassLoader);
try {
CtClass baseClass = generateBaseClass();
FileObject databaseDir = root.resolveFile(database.getDatabaseName());
databaseDir.deleteAll();
databaseDir.createFolder();
FileObject baseClassFile = databaseDir.resolveFile("BaseEntity.class");
try (OutputStream outputStream = baseClassFile.getContent().getOutputStream()) {
outputStream.write(baseClass.toBytecode());
}
for (Table table : mappableTables) {
generateClass(table);
}
for (Table table : mappableTables) {
mapRelationships(table);
}
for (Table table : mappableTables) {
byte[] classFile = getClassFile(table);
FileObject location = getEntityLocation(root, table);
try (OutputStream outputStream = location.getContent().getOutputStream()) {
outputStream.write(classFile);
}
}
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
return buildSessionFactory(new JavaCodeBase(root), mappableTables, externallyMappedTables);
}
use of com.manydesigns.portofino.model.database.Table in project Portofino by ManyDesigns.
the class SessionFactoryBuilder method buildSessionFactory.
public SessionFactoryAndCodeBase buildSessionFactory(CodeBase codeBase, List<Table> tablesToMap, List<Table> externallyMappedTables) {
BootstrapServiceRegistryBuilder bootstrapRegistryBuilder = new BootstrapServiceRegistryBuilder();
DynamicClassLoaderService classLoaderService = new DynamicClassLoaderService();
bootstrapRegistryBuilder.applyClassLoaderService(classLoaderService);
BootstrapServiceRegistry bootstrapServiceRegistry = bootstrapRegistryBuilder.build();
Map<String, Object> settings = setupConnection();
ServiceRegistry standardRegistry = new StandardServiceRegistryBuilder(bootstrapServiceRegistry).applySettings(settings).build();
MetadataSources sources = new MetadataSources(standardRegistry);
List<String> externallyMappedClasses = new ArrayList<>();
try {
for (Table table : tablesToMap) {
Class persistentClass = getPersistentClass(table, codeBase);
sources.addAnnotatedClass(persistentClass);
classLoaderService.classes.put(persistentClass.getName(), persistentClass);
if (entityMode == EntityMode.POJO) {
table.setActualJavaClass(persistentClass);
}
}
for (Table table : externallyMappedTables) {
sources.addAnnotatedClass(table.getActualJavaClass());
externallyMappedClasses.add(table.getActualJavaClass().getName());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
Metadata metadata = metadataBuilder.build();
if (entityMode == EntityMode.MAP) {
metadata.getEntityBindings().forEach((PersistentClass c) -> {
if (!externallyMappedClasses.contains(c.getClassName())) {
c.setClassName(null);
if (c.getIdentifier() instanceof Component) {
Component component = (Component) c.getIdentifier();
component.setComponentClassName(null);
component.setDynamic(true);
}
}
});
}
org.hibernate.boot.SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
return new SessionFactoryAndCodeBase(sessionFactoryBuilder.build(), codeBase);
}
use of com.manydesigns.portofino.model.database.Table in project Portofino by ManyDesigns.
the class SessionFactoryBuilder method mapManyToOne.
protected void mapManyToOne(ForeignKey foreignKey) throws CannotCompileException, NotFoundException {
CtClass cc = getMappedClass(foreignKey.getFromTable());
ClassFile ccFile = cc.getClassFile();
ConstPool constPool = ccFile.getConstPool();
Table toTable = foreignKey.getToTable();
CtField field = new CtField(getMappedClass(toTable), foreignKey.getActualOnePropertyName(), cc);
cc.addField(field);
AnnotationsAttribute fieldAnnotations = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annotation;
annotation = new Annotation(ManyToOne.class.getName(), constPool);
fieldAnnotations.addAnnotation(annotation);
List<MemberValue> joinColumnsValue = new ArrayList<>();
for (Reference reference : foreignKey.getReferences()) {
annotation = new Annotation(JoinColumn.class.getName(), constPool);
annotation.addMemberValue("insertable", new BooleanMemberValue(false, constPool));
annotation.addMemberValue("updatable", new BooleanMemberValue(false, constPool));
annotation.addMemberValue("name", new StringMemberValue(jpaEscape(reference.getFromColumn()), constPool));
annotation.addMemberValue("referencedColumnName", new StringMemberValue(jpaEscape(reference.getToColumn()), constPool));
joinColumnsValue.add(new AnnotationMemberValue(annotation, constPool));
}
annotation = new Annotation(JoinColumns.class.getName(), constPool);
ArrayMemberValue joinColumns = new ArrayMemberValue(new AnnotationMemberValue(constPool), constPool);
joinColumns.setValue(joinColumnsValue.toArray(new MemberValue[0]));
annotation.addMemberValue("value", joinColumns);
finalizeRelationshipProperty(cc, field, annotation, fieldAnnotations);
}
Aggregations