1

I am a hibernate learner. I have came to know about google-reflections library when I was researching on how to make dynamic POJO class when Only Table and schema name is provided i.e.

try {
        sessionFactory = new StringUtil().getSessionFactory(className);
        session = sessionFactory.openSession();

        sessionImp = (SessionImpl) session;

        System.out.println("Product name ["
                + sessionImp.connection().getMetaData()
                        .getDatabaseProductName() + "] table name "+tableName);
        metadata = sessionImp.connection().getMetaData();
        tables = metadata.getTables(null, "SDP", null,
                new String[] { "TABLE" });
        // tables = metadata.getTables( null, "public", null, new
        // String[]{"TABLE"} );//Postgres

        ResultSet rs = metadata.getExportedKeys("SDP", "SDP", tableName);

        while (rs.next()) {
            PojoGenerator.pkey = rs.getString("PKCOLUMN_NAME");

        }

        System.out.println("Primary key of Table is ["+PojoGenerator.pkey+"]");
        while (tables.next()) {
            tName = tables.getString(3);

            if (tName.equalsIgnoreCase(tableName)) {
                columns = metadata.getColumns("SDP", "SDP", tName, null);
                // columns = metadata.getColumns("sdp", "public", tName,
                // null);//Postgres

                while (columns.next()) {

                    tableMetadata = new TableMetadata();
                    tableMetadata.setColumnName(columns.getString("COLUMN_NAME"));
                    tableMetadata.setPropertyName(new StringUtil().getWordCaseNames(columns.getString("COLUMN_NAME")));
                    //tableMetadata.setRealColumnName( columns.getString("COLUMN_NAME") );
                    tableMetadata.setColumnType(new StringUtil().dbToJavaDataType(
                                    columns.getString("TYPE_NAME"),
                                    columns.getInt("COLUMN_SIZE"),
                                    columns.getString("DECIMAL_DIGITS")));
                    tableMetadata.setColumnLength(columns.getInt("COLUMN_SIZE"));
                    tableMetadata.setSession(session);
                    list.add(tableMetadata);

                }
                columns = null;
                tName = null;
            }
        }




    } catch (Exception e) {
        e.printStackTrace();
    }

This metadata helped me to generate POJO:

public static Class generate(String className, Map<String, Class<?>> properties, List tableDetails) throws NotFoundException, CannotCompileException {
    boolean needToCreateClass   = false;
    Object obj                  = null;
    Class<?> clazz              = null;
    CtMethod getterMethod       = null;
    TableMetadata tableMetadata = null;
    int numberOfColumnsInTable  = 0;
    try {
        clazz = Class.forName(className);
        obj = clazz.newInstance();
        if ( obj != null ){
            needToCreateClass = false;
        }else{
            needToCreateClass = true;
        }
    }catch (Exception e){
        needToCreateClass = true;
    }

    System.out.println("Need to create a class ["+needToCreateClass+"]");

    if ( needToCreateClass ) {

        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.makeClass(className);

        // add this to define a super class to extend
        // cc.setSuperclass(resolveCtClass(MySuperClass.class));

        // add this to define an interface to implement
        cc.addInterface(resolveCtClass(Serializable.class));

        ClassFile cf = cc.getClassFile();
        ConstPool constpool = cf.getConstPool();
        AnnotationsAttribute attrTable = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        AnnotationsAttribute attrColumn = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        Annotation [] tableAnnotations = new Annotation[]{new Annotation("javax.persistence.Entity", constpool), new Annotation("javax.persistence.Table", constpool) };


        for (Entry<String, Class<?>> entry : properties.entrySet()) {

            cc.addField(new CtField(resolveCtClass(entry.getValue()), entry.getKey(), cc));

           // System.out.println("Key is ["+entry.getKey()+"]");
            getterMethod = generateGetter(cc, entry.getKey(), entry.getValue());
            // add getter
            cc.addMethod(getterMethod);

            if ( numberOfColumnsInTable == 0 ) {

                tableAnnotations[1].addMemberValue("name", new StringMemberValue("CRBT_RBT", constpool));
                tableAnnotations[1].addMemberValue("schema", new StringMemberValue("SDP", constpool));
                attrTable.setAnnotations(tableAnnotations);
                cc.getClassFile().addAttribute(attrTable);
                attrTable = null;
            }



            attrColumn = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
            Annotation annot1[] = {new Annotation("javax.persistence.Id", constpool),new Annotation("javax.persistence.Column", constpool)};
            Annotation annot2[] = {new Annotation("javax.persistence.Column", constpool)};
            tableMetadata = (TableMetadata)tableDetails.get( numberOfColumnsInTable );
            if ( numberOfColumnsInTable < tableDetails.size() ) {
                String realColumnName=new StringUtil().getRealName( entry.getKey());

                if(realColumnName.equalsIgnoreCase(pkey)){
                    annot1[1].addMemberValue("name", new StringMemberValue( realColumnName , constpool ) );
                    attrColumn.setAnnotations(annot1);
                }else{
                    annot2[0].addMemberValue("name", new StringMemberValue( realColumnName , constpool ) );
                    attrColumn.setAnnotations(annot2);
                }
                numberOfColumnsInTable++;
            }

            getterMethod.getMethodInfo().addAttribute(attrColumn);

            // add setter
            cc.addMethod(generateSetter(cc, entry.getKey(), entry.getValue()));
        }
        try {
            cc.writeFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        /*
        Validation for applied annotations
      */
     try {
         Object[] all = cc.getAnnotations();
         int k = 0;
         for (Object object : all) {
             System.out.println(all[k]);
             k++;
         }
     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     }
     /* Validation End */
        return cc.toClass();
    }else{
        return clazz;
    }
}

but now I need to map those Dynamically created POJO with hibernate configuration. So my question comes here: 1. Can I use reflections library for that? 2. How? 3. If not, Is there any Other solutions besides creating .hbm.xml files for each class?

please help. Thanks in advance.

UPDATE :

I have an Idea but I don't know how it will work. Idea: I will create .hbm.xml files for each class dynamically and will map the package of those classes in hibernate.cfg.xml.

But 1.I don't know How to scan the mapping file by package mapping. 2. I don't even know if it is possible or not and if possible then how?

yashpal bharadwaj
  • 323
  • 2
  • 6
  • 14

0 Answers0