0

Probably the only way to do this is to keep a list of static final Strings but if anyone has any idea it is welcome.

I have a POJO and a database table. The columns(properties) are the same as the class members of the POJO. I want to avoid (it is a fairly big program) to write getColumn("username") but instead write something like getColumn(UserPOJO.getUsername().getActualMemberNameInAString())

The only way I can think of is to have a UserPOJO class with just static variables and update it when I add members in the class. The second option is to have all the properties as enums but that is bad I think in a number of levels.

What I would like to have is a way to get the member name that corresponds to the getter method. Some kind of reflection?

Problem to be solved is typos in a huge codebase. I overemphasize here because I have received comments and answers that are not what I am asking for.

Note that I am not using any framework or ORM tool. I am using a Graph database that maps all columns to a Vertex and then you need to do .getProperty(string s) to get an Object. And I do this many times in the code

arisalexis
  • 2,079
  • 2
  • 21
  • 42
  • Using some tool? http://www.querydsl.com/. – Aleksandr M Apr 09 '15 at 12:44
  • Are you crafting the mapping by hand? You could use something like MyBatis or Spring JDBC templates to map for you. Generally you would use annotations to say which database columns the fields in the POJO map to and then the framework does the boring grunt work. – Paolo Apr 09 '15 at 12:45
  • You say 'keep a list', mayby clarify or edit that so people don't think you are storing the Strings in a list... – Tom Jonckheere Apr 09 '15 at 12:45
  • Is there a reason you need to do it this way? It seems very fragile. Maybe explain the problem you are trying to solve and a better way might reveal itself. – markbernard Apr 09 '15 at 12:46
  • @markbernard problem is fairly easy to see. Typos. – arisalexis Apr 09 '15 at 12:47
  • You could use reflection to extract the names. If you write appropriate functions it could look something like this: `getColumn(name(on(UserPOJO.class).getUsername()))`. Whether that is worth the effort however... – blalasaadri Apr 09 '15 at 12:47
  • @arisalexis I am not saying it is not easy it is just very fragile. A database should not have this intimate knowledge of the Java classes that are being represented in the database. Are you just trying to avoid using Hibernate or something similar? If so then annotations may be the way to go. – markbernard Apr 09 '15 at 12:50
  • @markbernard I am writing vanilla Java code. No hibernate. I am using a graph database with tinkerpop blueprints but that's irrelevant. – arisalexis Apr 09 '15 at 12:51
  • "`getColumn("username")` but instead write `getColumn(UserPOJO.USERNAME)`" Why bother? If you use `POJO.USERNAME` only once (which would seem to be the case) you have gained nothing. – Raedwald Apr 09 '15 at 12:55
  • @Raedwald I don't get it? I am using many times POJO.USERNAME in the codebase and that is the problem in the first place. – arisalexis Apr 09 '15 at 12:57
  • Why would you use `POJO.USERNAME` outside your repository object (DAO)? – Raedwald Apr 09 '15 at 12:58
  • Discussing my codebase I think is outside of the scope of the question , but I have many functions that do a lot of things. I do not just map a row to an object (ORM) but have many functions in the DAO that do getColumn("username"). Why is that weird? I am not using a relational database. an example would be: if (!erequest.getVertex(Direction.OUT).getProperty("username").toString().equalsIgnoreCase(vuser.getProperty("username").toString())). multiply by 1000 – arisalexis Apr 09 '15 at 13:00
  • "Discussing my codebase I think is outside of the scope of the question": not if you actually have an XY Problem. – Raedwald Apr 09 '15 at 13:13
  • @arisalexis You should not be performing calculations in the DAO. The DAO is simply mapping from the DB to Java objects. You do any calculations on the Java objects. – markbernard Apr 09 '15 at 13:36
  • Thank you for your interest but generally discussing what a DAO should do would take days. But I am not using this, not using relational databases etc.Again, using Vertices in Graph databases is very different from what most of the standard Spring,DAO,Factory style programmers use.I was hoping of a clever way to do some kind of reflection to get the member name that corresponds to the getter or setter. In any case replace DAO with a bunch of functions that do stuff to tables. Database Service? – arisalexis Apr 09 '15 at 13:42

2 Answers2

0

You have multiple options:

If you only need the name once, I wouldn't bother to create constants for them.

In one of your comments you stated you will use it a lot and in different places, you could create a class that stores all those strings as constants. At least you will avoid typos, and your code wont be littered with strings.

You could use reflection but that would overcomplicate things (in my opinion).

I wouldn't exclude using enums as an option. This SO answer explains it better, then I could do...

Community
  • 1
  • 1
Tom Jonckheere
  • 1,630
  • 3
  • 20
  • 37
0

My understanding of this question is you want minimum code change when your underlaying Database Table get changed.

so let me put it as , say I have a table Info as

CREATE TABLE Info (
field1 INTEGER ,
field2 VARCHAR(1)
);

and I am expecting field3 could be added in future then I need a solution where I do not need to add extra code for getting information for field3.

Please confirm if the understanding is correct ? if yes then you can use below strategy

/**
 * generic Method for executing Any RAW SQL Query.
 * for e.g. sql = "select * from Info"; 
 */


 public List<Map<String,String>> executeQuery(String sql) throws Exception {
        logger.info("executing SQL  = "+sql);
        List<Map<String,String>> resultList = new ArrayList<Map<String, String>>();
        Statement statement=null;
        ResultSet resultSet=null;
        ResultSetMetaData metaData = null;
        try{
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            metaData = resultSet.getMetaData();
            int noOfColumns = metaData.getColumnCount();
            while(resultSet.next()){
                Map<String,String> row = new HashMap<String, String>();
                for(int i =1;i<=noOfColumns;i++){
                    row.put(metaData.getColumnName(i), resultSet.getString(metaData.getColumnName(i)));
                }
                resultList.add(row);
            }
        } catch (SQLException e) {
            throw new Exception(" Exception while executing query on database. Reason  "+e.getMessage());
        }
        finally {
            closeResources(statement, resultSet);
        }
        return resultList;
    }

for input String sql = "select * from Info"; Here you will get all records of Info Table with key-value pair where key suggests columnName and value suggests value of that column.

And this is as good as dynamic ,even if we add extra columns we will get that information in our Map also it does not require to use any framework

Shirishkumar Bari
  • 2,692
  • 1
  • 28
  • 36