Search in sources :

Example 1 with Table

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));
        }
    });
}
Also used : Table(com.manydesigns.portofino.model.database.Table) Updatable(com.manydesigns.elements.annotations.Updatable) javax.persistence(javax.persistence) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 2 with Table

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;
}
Also used : Table(com.manydesigns.portofino.model.database.Table) Column(com.manydesigns.portofino.model.database.Column)

Example 3 with Table

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);
}
Also used : ConstPool(javassist.bytecode.ConstPool) URL(java.net.URL) LoggerFactory(org.slf4j.LoggerFactory) StringUtils(org.apache.commons.lang3.StringUtils) SequenceGenerator(com.manydesigns.portofino.model.database.SequenceGenerator) TableGenerator(com.manydesigns.portofino.model.database.TableGenerator) URLClassLoader(java.net.URLClassLoader) PersistentClass(org.hibernate.mapping.PersistentClass) Column(com.manydesigns.portofino.model.database.Column) MultiTenancyImplementation(com.manydesigns.portofino.persistence.hibernate.multitenancy.MultiTenancyImplementation) Method(java.lang.reflect.Method) StandardServiceRegistry(org.hibernate.boot.registry.StandardServiceRegistry) javassist(javassist) Immutable(org.hibernate.annotations.Immutable) PersistentDateTime(org.jadira.usertype.dateandtime.joda.PersistentDateTime) FileSystemException(org.apache.commons.vfs2.FileSystemException) Collectors(java.util.stream.Collectors) JavaCodeBase(com.manydesigns.portofino.code.JavaCodeBase) MetadataSources(org.hibernate.boot.MetadataSources) Serializable(java.io.Serializable) Nullable(org.jetbrains.annotations.Nullable) ForeignKey(com.manydesigns.portofino.model.database.ForeignKey) javassist.bytecode.annotation(javassist.bytecode.annotation) FileName(org.apache.commons.vfs2.FileName) Modifier(java.lang.reflect.Modifier) NotNull(org.jetbrains.annotations.NotNull) TypeDefs(org.hibernate.annotations.TypeDefs) Types(java.sql.Types) BootstrapServiceRegistryBuilder(org.hibernate.boot.registry.BootstrapServiceRegistryBuilder) java.util(java.util) javax.persistence(javax.persistence) AvailableSettings(org.hibernate.cfg.AvailableSettings) CodeBase(com.manydesigns.portofino.code.CodeBase) StandardServiceRegistryBuilder(org.hibernate.boot.registry.StandardServiceRegistryBuilder) Metadata(org.hibernate.boot.Metadata) VFS(org.apache.commons.vfs2.VFS) Table(com.manydesigns.portofino.model.database.Table) OutputStream(java.io.OutputStream) Updatable(com.manydesigns.elements.annotations.Updatable) Logger(org.slf4j.Logger) ClassFile(javassist.bytecode.ClassFile) EntityMode(org.hibernate.EntityMode) ClassLoaderServiceImpl(org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl) MultiTenancyStrategy(org.hibernate.MultiTenancyStrategy) BootstrapServiceRegistry(org.hibernate.boot.registry.BootstrapServiceRegistry) DateTime(org.joda.time.DateTime) DatabasePlatform(com.manydesigns.portofino.model.database.platforms.DatabasePlatform) IOException(java.io.IOException) com.manydesigns.portofino.model.database(com.manydesigns.portofino.model.database) FileObject(org.apache.commons.vfs2.FileObject) GenericGenerator(org.hibernate.annotations.GenericGenerator) ServiceRegistry(org.hibernate.service.ServiceRegistry) AnnotationsAttribute(javassist.bytecode.AnnotationsAttribute) Configuration(org.apache.commons.configuration2.Configuration) MetadataBuilder(org.hibernate.boot.MetadataBuilder) Component(org.hibernate.mapping.Component) TypeDef(org.hibernate.annotations.TypeDef) Table(com.manydesigns.portofino.model.database.Table) URLClassLoader(java.net.URLClassLoader) OutputStream(java.io.OutputStream) URLClassLoader(java.net.URLClassLoader) FileObject(org.apache.commons.vfs2.FileObject) JavaCodeBase(com.manydesigns.portofino.code.JavaCodeBase)

Example 4 with Table

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);
}
Also used : BootstrapServiceRegistryBuilder(org.hibernate.boot.registry.BootstrapServiceRegistryBuilder) Table(com.manydesigns.portofino.model.database.Table) StandardServiceRegistryBuilder(org.hibernate.boot.registry.StandardServiceRegistryBuilder) MetadataBuilder(org.hibernate.boot.MetadataBuilder) MetadataSources(org.hibernate.boot.MetadataSources) Metadata(org.hibernate.boot.Metadata) BootstrapServiceRegistry(org.hibernate.boot.registry.BootstrapServiceRegistry) FileSystemException(org.apache.commons.vfs2.FileSystemException) IOException(java.io.IOException) FileObject(org.apache.commons.vfs2.FileObject) PersistentClass(org.hibernate.mapping.PersistentClass) StandardServiceRegistry(org.hibernate.boot.registry.StandardServiceRegistry) BootstrapServiceRegistry(org.hibernate.boot.registry.BootstrapServiceRegistry) ServiceRegistry(org.hibernate.service.ServiceRegistry) Component(org.hibernate.mapping.Component) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 5 with Table

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);
}
Also used : ConstPool(javassist.bytecode.ConstPool) ClassFile(javassist.bytecode.ClassFile) Table(com.manydesigns.portofino.model.database.Table) AnnotationsAttribute(javassist.bytecode.AnnotationsAttribute)

Aggregations

Table (com.manydesigns.portofino.model.database.Table)9 Column (com.manydesigns.portofino.model.database.Column)3 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)3 ClassFile (javassist.bytecode.ClassFile)3 ConstPool (javassist.bytecode.ConstPool)3 PersistentClass (org.hibernate.mapping.PersistentClass)3 Updatable (com.manydesigns.elements.annotations.Updatable)2 IOException (java.io.IOException)2 javax.persistence (javax.persistence)2 FileObject (org.apache.commons.vfs2.FileObject)2 FileSystemException (org.apache.commons.vfs2.FileSystemException)2 Metadata (org.hibernate.boot.Metadata)2 MetadataBuilder (org.hibernate.boot.MetadataBuilder)2 MetadataSources (org.hibernate.boot.MetadataSources)2 BootstrapServiceRegistry (org.hibernate.boot.registry.BootstrapServiceRegistry)2 BootstrapServiceRegistryBuilder (org.hibernate.boot.registry.BootstrapServiceRegistryBuilder)2 StandardServiceRegistry (org.hibernate.boot.registry.StandardServiceRegistry)2 StandardServiceRegistryBuilder (org.hibernate.boot.registry.StandardServiceRegistryBuilder)2 Component (org.hibernate.mapping.Component)2 ServiceRegistry (org.hibernate.service.ServiceRegistry)2