Reflection inquiry?

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 2173 Views - Last Post: 16 July 2012 - 10:46 PM

#1 mensahero  Icon User is offline

  • I Desire...
  • member icon

Reputation: 17
  • View blog
  • Posts: 678
  • Joined: 26-May 08

Reflection inquiry?

Posted 10 July 2012 - 08:48 PM

I'm creating a class the will dynamically create SQL statements based on a passed object using simple Reflection. Is this advisable? what is the disadvantages of my approach? is there any other possible better way of accomplishing this without using Reflection?

Note: Hibernate or any ORM is not an option.

Here's my code:

TestUserDAO.java

 
public class TestUserDAO {


	public static void main(String[] args) {
		
		DAO userDAO = new UserDAO();
		Object user = new User();
		
		userDAO.addNewRecord(user);

	}

}



DAO.java


import java.lang.reflect.Field;

public abstract class DAO {
	
	public void addNewRecord(Object obj){
		
		String sql = generateSQL(obj);
		
		System.out.println(sql);		
		
	}
	
	private String generateSQL(Object obj){
		
		Field fields[] = obj.getClass().getDeclaredFields();
		StringBuilder builder = new StringBuilder();
		
		for(int i = 0; i < fields.length; i ++) {
			
			if(builder.length() > 0){
				builder.append(",");			
			}
			
			builder.append(fields[i].getName());
		}
		
		return builder.toString();
		
	}

}




User.java -Plain Java Object

public class User {	

	private int id_user;
	private String firstname;
	private String lastname;
	private String username;
	private String password;
	
	public User(){}	
	
	
	public int getId_user() {
		return id_user;
	}

	public void setId_user(int id_user) {
		this.id_user = id_user;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	};

	
}





UserDAO.java -It just extends DAO, so it contains nothing for now.

Running the application will print "id_user,firstname,lastname,username,password" on the console.

Thanks in advance.

This post has been edited by mensahero: 10 July 2012 - 09:01 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Reflection inquiry?

#2 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2728
  • View blog
  • Posts: 11,470
  • Joined: 20-September 08

Re: Reflection inquiry?

Posted 11 July 2012 - 03:24 AM

Quote

is there any other possible better way of accomplishing this without using Reflection?

Well, you can obviously only avoid reflection if your code limits itself to objects where the internal organisation is known. That will make your persistence code inflexible by definition.

Quote

Note: Hibernate or any ORM is not an option.

Well, you must have a good reason, but all you're doing is reinventing it, probably badly (and we'd all perform badly, given normal constraints)
Was This Post Helpful? 0
  • +
  • -

#3 mensahero  Icon User is offline

  • I Desire...
  • member icon

Reputation: 17
  • View blog
  • Posts: 678
  • Joined: 26-May 08

Re: Reflection inquiry?

Posted 11 July 2012 - 03:36 AM

View Postg00se, on 11 July 2012 - 03:24 AM, said:

Quote

is there any other possible better way of accomplishing this without using Reflection?

Well, you can obviously only avoid reflection if your code limits itself to objects where the internal organisation is known. That will make your persistence code inflexible by definition.


This code below is the only part where I'll be using reflection. Will this line really degrade performance or using reflection is really a bad idea?

 
Field fields[] = obj.getClass().getDeclaredFields();



About not using Hibernate or ORM. I just can't use them since I was told to use plain JDBC in Spring. I don't intend on re-inventing anything, I just want to dynamically create SQL string based on Plain Java Objects.
Was This Post Helpful? 0
  • +
  • -

#4 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2728
  • View blog
  • Posts: 11,470
  • Joined: 20-September 08

Re: Reflection inquiry?

Posted 11 July 2012 - 03:45 AM

The performance overhead of reflection is sometimes exaggerated. I can only say, if in doubt, benchmark it.

As for doing this in Spring, it's so vast that i'd be surprised if Spring didn't already have some 'mini-ORM' class, although see my previous remarks on wheel reinvention (Spring might avoid that too)

e.g. (a quick google) THIS

This post has been edited by g00se: 11 July 2012 - 03:49 AM
Reason for edit:: update

Was This Post Helpful? 1
  • +
  • -

#5 mensahero  Icon User is offline

  • I Desire...
  • member icon

Reputation: 17
  • View blog
  • Posts: 678
  • Joined: 26-May 08

Re: Reflection inquiry?

Posted 11 July 2012 - 07:36 PM

View Postg00se, on 11 July 2012 - 03:45 AM, said:

The performance overhead of reflection is sometimes exaggerated. I can only say, if in doubt, benchmark it.


How do I do that benchmarking? is there a tool? method or a standard practice? or just plain manual observation?

Quote

e.g. (a quick google) THIS


Where currently using that and this is how we do it.


String sql = "insert into t_actor (first_name, last_name, address) values (?, ?, ?)"
this.jdbcTemplate.update( sql,"Leonor", "Watling", "Some address..");




That's why I want to dynamically generate SQL string since its very tedious to code it and those parameters manually. Then I was told that Reflection would degrade performance.

This post has been edited by mensahero: 11 July 2012 - 07:37 PM

Was This Post Helpful? 0
  • +
  • -

#6 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2728
  • View blog
  • Posts: 11,470
  • Joined: 20-September 08

Re: Reflection inquiry?

Posted 12 July 2012 - 01:56 AM

Quote

How do I do that benchmarking?


Off the top of my head you could write some code with an execution path with and without introspection and time the difference

Quote

Where currently using that and this is how we do it

Actually it looked like JDBCTemplate was able to do reflection introspection but it looks like i could be wrong. I wouldn't mind betting something else in Spring can, possibly a helper for JDBCTemplate
Was This Post Helpful? 0
  • +
  • -

#7 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5835
  • View blog
  • Posts: 12,689
  • Joined: 16-October 07

Re: Reflection inquiry?

Posted 12 July 2012 - 06:35 AM

View Postmensahero, on 11 July 2012 - 10:36 PM, said:

Where currently using that and this is how we do it.
... SQL string since its very tedious to code it and those parameters manually.


Yes... yes it is. Suck it up. ;)

There are a number of pitfalls in an automatic approach. Not the least of which are any number of edge cases that will blow you out of the water. What if you need to hold variable that isn't stored in the data base? What if the field names can't match due to DB restrictions? What is the identity?

That last one is tricky. You really want your data objects to have some idea of the primary key. In this way they can figure out how to do essential operations like delete and update rather than just insert. Of, if the PK is automatic...

If you really want to do something automatically, you can generate standard source code using reflection. Then, if there are edge cases, you can make the edits without worry. I've done very large systems like this; generating base code and then being able to tweak when needed.

Every automatic, does it for you, no extra code needed, solution you find will be brittle. You will always find a case that doesn't match and you have to hunker down and write something custom. Trust me, all frameworks are rainbows and unicorns until you hit the first snag; then it's usually hobgoblins galore.
Was This Post Helpful? 1
  • +
  • -

#8 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7765
  • View blog
  • Posts: 13,131
  • Joined: 19-March 11

Re: Reflection inquiry?

Posted 12 July 2012 - 06:43 AM

This does seem like a dubious proposal to me. If I understand you correctly, you want to pass in random objects and write them to your DB using the field name as the key?
This looks to me a lot like you're writing a properties file, but with Java syntax. It has all of the disadvantages of reading a properties file and writing all of its key/value pairs - for example, you have no reason to suppose that the same data will get the same key from file to file, to pick one at random - plus the disadvantages of you have to write executable Java code to pass your data around.

If you're going to go to the trouble of writing a class, why not go the extra yard and arrange things so that it knows how to dump its data to your DB?

View Postbaavgai, on 12 July 2012 - 08:35 AM, said:

Trust me, all frameworks are rainbows and unicorns until you hit the first snag; then it's usually hobgoblins galore.

Piss off, some of my best friends are hobgoblins. What are you, racist?

This post has been edited by jon.kiparsky: 12 July 2012 - 06:43 AM

Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8334
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Reflection inquiry?

Posted 13 July 2012 - 03:48 AM

What don't you simply save your Object as a Java object in the DB ?
No need to separate in different columns each of the fields. So if a field is added or suppressed it won't matter. If added old serialized object will have them initialized to 0,false, null. If deleted, they will just be ignored.
Was This Post Helpful? 0
  • +
  • -

#10 Ghlavac  Icon User is offline

  • D.I.C Addict

Reputation: 84
  • View blog
  • Posts: 519
  • Joined: 14-January 09

Re: Reflection inquiry?

Posted 13 July 2012 - 06:18 AM

To get around the issues of field names with database I would suggest you add some annotation stuff to your classes, make your own and then access those with reflection to refine the bindings enough to be less irritating.
Was This Post Helpful? 0
  • +
  • -

#11 mensahero  Icon User is offline

  • I Desire...
  • member icon

Reputation: 17
  • View blog
  • Posts: 678
  • Joined: 26-May 08

Re: Reflection inquiry?

Posted 15 July 2012 - 11:51 PM

@baavgai

baavgai said:

There are a number of pitfalls in an automatic approach. Not the least of which are any number of edge cases that will blow you out of the water. What if you need to hold variable that isn't stored in the data base? What if the field names can't match due to DB restrictions? What is the identity?


The fields on the database tables is exactly the same with those Plain Java Objects that's why I want to automate it using Reflection. The PK is automatically generated and spring already has a way of retrieving them. My main problem is "REFLECTION WILL GREATLY DEGRADE PERFORMANCE" even if I used it as minimal as possible(Just for generating SQL Strings).

@jon.kiparsky

jon.kiparsky said:

This does seem like a dubious proposal to me. If I understand you correctly, you want to pass in random objects and write them to your DB using the field name as the key?


I don't know why dubious means but I'm actually passing Plain Java Objects that has corresponding table on the database with the same fields. eg: Events.java = Tbl_events ... Class attributes = Table Fields.. PK are auto-incremented values and Spring JDBC has decent way of retrieving them during adding new record.

@pbl

pbl said:

What don't you simply save your Object as a Java object in the DB ?
No need to separate in different columns each of the fields. So if a field is added or suppressed it won't matter. If added old serialized object will have them initialized to 0,false, null. If deleted, they will just be ignored.


I'm not quite sure what you meant by this. Is this method advisable on a Relational Database Driven application?

@Ghlavac

Ghlavac said:

To get around the issues of field names with database I would suggest you add some annotation stuff to your classes, make your own and then access those with reflection to refine the bindings enough to be less irritating.


Have you tried doing this? does it have noticeable performance issue?
Was This Post Helpful? 0
  • +
  • -

#12 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7765
  • View blog
  • Posts: 13,131
  • Joined: 19-March 11

Re: Reflection inquiry?

Posted 16 July 2012 - 06:51 AM

Why not simply make java objects that can unload their payload when the database goes to read them?

You could even have them construct an SQL query to write their contents to the database, as one if their methods.
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5835
  • View blog
  • Posts: 12,689
  • Joined: 16-October 07

Re: Reflection inquiry?

Posted 16 July 2012 - 07:02 AM

It's really not reflection's fault; it's the methodology. You'd only need to use reflect once per class. How long does that take? Now, if you did it for every single transaction, now we're talking overhead.

What you want, among other things, is persistence. Persistence mechanisms in Java are legion. Take a good look at EJB Entity and using the database as the datastore. More here: http://www.javabeat....entity-manager/

The thing is, you're using Spring which already supplies this functionality: http://static.spring...rence/jdbc.html

If you knew what you wanted those classes to generally look like, you could write code to generate that code. Use reflection once, as I said before.

So, back to my first statement: suck it up and write some code.
Was This Post Helpful? 1
  • +
  • -

#14 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7765
  • View blog
  • Posts: 13,131
  • Joined: 19-March 11

Re: Reflection inquiry?

Posted 16 July 2012 - 07:27 AM

View Postmensahero, on 16 July 2012 - 01:51 AM, said:

My main problem is "REFLECTION WILL GREATLY DEGRADE PERFORMANCE" even if I used it as minimal as possible(Just for generating SQL Strings).


If this is your concern, benchmark it. This has been suggested already - develop a trial model and see if it takes excessive time. I don't think application performance is your big issue here, I think it's developer performance. Doing this with reflection seems a pretty lousy way to go about it, not least because it's going to be difficult to maintain, as compared with just writing ordinary Java.


Quote

I don't know why dubious means but I'm actually passing Plain Java Objects that has corresponding table on the database with the same fields. eg: Events.java = Tbl_events ... Class attributes = Table Fields.. PK are auto-incremented values and Spring JDBC has decent way of retrieving them during adding new record.




Here, let's suppose you have an Event that you want written to your database.

Events.java has fields date, time, place, participants, description, maybe a few other fields. These are stored as Java-flavored objects.
The object has methods to import and export its fields by writing a query to a database (presumably it gets the DB access from the running class), and it can also populate itself by whatever other means you find useful, ie, it can read a line from a flat data file if you need, or take direct keyboard input, or whatever.

That's plain ordinary Java, you can test it and debug it and maintain it.
Now, why do you need Reflection?
Was This Post Helpful? 1
  • +
  • -

#15 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10573
  • View blog
  • Posts: 39,151
  • Joined: 27-December 08

Re: Reflection inquiry?

Posted 16 July 2012 - 08:28 AM

Since this is a Java EE topic, I'll move this to the Java EE forum.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2