Using sqls in JSP - What is the best practice? - java

Say, You have an application which lists down users in your application. Ideally, if you were writing code to achieve this in Java, irrespective of what your UI layer is, I would think that you would write code which retrieves result set from the database and maps it to your application object. So, in this scenario, you are looking at your ORM / Data layer doing its thing and creating a list of "User" objects.
Let's assume that your User object looks as follows:
public class User {
private String userName;
private int userid;
}
You can now use this list of "User" objects, in any UI. (Swing / Webapp).
Now, imagine a scenario, where you have to list down the userName and a count of say, departments or whatever and this is a very specific screen in a webapp. So you are looking a object structure like this:
public class UserViewBean {
private String userName;
private int countDepartments;
}
The easiest way of doing this is writing SQL for retrieving department count along with user name in one query. If I you to write such a query, where would you have this query? In your jsp? But, if you were doing this in a MVC framework, would you move this query to your data layer, get the result set, convert it to UserViewBean and send it to your jsp in request scope? If you write queries directly into jsps/if you are making use of connections directly in JSP, isn't that a bad practice?
I know, some of you might say, 'hey, you got your object composition wrong! if department is linked to user, you would want to create a list of departments in your User object' - Yes, I agree. But, think of this scenario - Say, I don't need this department count information anywhere else in my application other than this one screen. Are you saying that whereever I load my User object from the database, I would have to load a list of dependency objects, even if I won't be using them? How long will your object graph get with all the relational integrity? Yes, I do know that you have ORMs for this very reason, so that you get benefits of lazy loading and stuff, but I dont have the privilage to use one.
The bottom line question here is:
Would you write sqls in to your JSP if it serves just one screen? OR
Would you compose an anemic object
that caters to your view and make
your business layer return this
object for this screen - just to make
it look a bit OOish? OR
irrespective of what your screen
demands, would you compose your
objects such that an object graph
is loaded and you would get the
size of that list?
What is the best practice here?

I would never put SQL in a JSP. I would use Spring MVC or Struts controllers, or servlets to contain all of that type of logic. It allows for better error handling among other things (you can forward to error pages when queries fail).
If you really must do this, use the JSTL SQL tags.

Personally, I take a simple pragmatic approach. If I was writing screen that just displays a list of users with their deparment count, so that the entire code is maybe a page, and I don't expect this code to be used on any other screen, I'd probably just throw it all in the JSP. Yes, I know there are all the MVC purists who will say, "business logic should never go in a JSP". But aside from a dogmatic rule, why not? What would it hurt in a case like this?
If I found that I had two screens, maybe one where I had to simply display the list and another where I had to do some additional processing on the list, then I would certainly pull the common code out into a class that was called from both places.
I believe that the criteria should be: What produces the most maintainable code? What is shortest and easiest to understand? What produces the least linkages between modules? etc.
I adamantly refuse to accept the principle: "In some cases this approach leads to problems, therefore never use it." If sometimes it leads to problems, then don't use it in the cases where it leads to problems. Or worse, "Somebody wrote it in a book, therefore it cannot be questioned." Sure, there are some rules that are valid 99.99% of the time, so it gets to be pointless to check if this particular case is an exception. But there are lots of rules that are good 51% of the time and people leap from "mostly" to "always".

Would you write sqls in to your JSP if it serves just one screen?
In a prototype, just as a quick hack - maybe. In any other situation, not to mention a production environment - NEVER.
Use a proper MVC framework to separate business logic from presentation.

I am not even sure that JSP should be used, but for trivial applications. If you really have to use them, use MVC pattern or encapsulate your logic in a JavaBean.

Have a look at JPA which allow you to do object manipulations which then is persisted in the database

I wouldn't put SQL in a jsp for fear of forgetting it in future maintenance. Think of the poor guy maintaining your code-- poor guy = you in 10 months or whenever the database is restructured-- and at least put all SQL in the same general region.

Related

Object builder that requires parameters based on other parameters

I am working with several external APIs on a business code that would be used by several developers that do not have the deep knowledge required to build meaningful queries to those APIs.
Those API retrieve data. For example, you can retrieve entities either based on their Key (direct access) or based on their Group (lists available entities). But if you choose to query by Key you have to provide an id, and if you query by Group you have to provide a groupName.
The APIs are bigger than that and more complex, with many possible use-cases. The main constraints are that:
Some parameters require the presence of other parameters
Some parameters put with other parameters produce no data at best, wrong data at worst.
I would love to fix the underlying APIs but they are outside our scope.
I think it might be good to enclose a bit those API and produced a APIService that can request(APIQuery query).
The basic thing I could do is to put conditions in the code to check that no developer instantiates the APIQuery with missing/incoherent parameters, however that would only be a runtime error. I would love for the developer to know when building their request that they can/cannot do something.
My two questions are:
Is there an extensible builder-like way to defer the responsibility of building itself to the object? Having 1 constructor per valid query is not a good solution, as there are many variables and "unspoken rules" here.
Is this even a good idea? Am I trying to over-engineer?
I'll answer your second question first:
Is this even a good idea? Am I trying to over-engineer?
The answer is an uncomfortable "it depends". It depends how bad the pain is, it depends how crucial it is to get this right. It depends on so many factors that we can't really tell.
And to your: is this possible?
Yes, a builder pattern can be extended to return specific builders when certain methods are called, but this can become complicated and mis-uses are possible.
For your specific example I'd make the QueryBuilder simply have two methods:
a byGroup method that takes a group value to filter on and returns a GroupQueryBuilder
a bykey method that takes a key value to filter on and returns a KeyQueryBuilder.
Those two classes can then have methods that are distinct to their respective queries and possibly extend a shared base class that provides common properties.
And their respective build methods could either return a APIQuery or distinct APIQueryByGroup/APIQueryByKey classes, whichever is more useful for you.
This can become way more complicated if you have multiple axis upon which queries can differ and at a certain point, it'll become very hard to map that onto types.

"Container" classes, good or bad practice, why?

I'm curious as to which is the better practice and the reasoning behind it, for this example I'm going to be using a social application which contains a 'friends' and a 'ignore' list with some custom logic based on them, (For sending messages directly, etc)
Which would be the better practice, and why?
Scenario 1:
class user {
List<> friends;
List<> ignores;
...
logical methods here
}
Scenario 2:
class User {
Social social;
...
}
class Social {
List<> friends;
List<> ignores;
...
logical methods here
}
I've seen both scenarios used throughout numerous applications and I'm curious as to which is the "Correct" way to lay it out in java, these will have methods such as
#addFriend(User user)
check ignore
check valid user
check other info
add to list
end
#getFriend(int id)
find friend by id
check online status
return friend
It seems like while have a 'Social' class may be a cleaner approach, does it really follow good practices? Seems like it'd use more memory/user just for cleaner code.
The reason why you have such constructs as your Social, most of the time, is that they represent a logical set of data and operations which is needed for different entities in your application.
If nothing other than User has those properties and actions, then there is no point in doing it separately from User. But you may design it separately anyway, for future uses (for example, if you want to be able to expand it later and you believe there will be other entities which will need Social functionality).
Looking at this from an object-oriented viewpoint, it means that the Social is a type. And then you have to ask yourself, is whether your User is_a Social or whether your User has_a Social. Does it make sense to say that the user has a "social subsystem" or is the user a "social object"? If the correct relation is is_a, then User should extend Social. If not, it should have a Social member, such as you described.
However, in Java, since you can't have multiple inheritance of implementation, sometimes your type may inherit from several types, and you have to decide which of them to extend. Many times, you simulate multiple inheritance of implementation, by having a member of what should have been the "second parent class", declare all the methods in your class, and delegate them to that member.
So the general guidelines are, more or less:
If in your application's domain, the only class where it will make sense to have friends and ignores and their operations is User, and no other conceivable entity would ever need them, then implement them directly in User.
If other entities may need similar functionality, and not all of them extend User anyway, you may consider this functionality to be an entity or class in its own right, and then you should have every class which has an is_a relationship to this entity extend it.
If Java's limitations of multiple inheritance don't allow extending directly, as it makes more sense for the class to extend some other class, you should embed an object and delegate the operations.
There may be other practical reasons to separate the Social entity from User, despite User being the only class to use them. For example, if you have several different possible implementations of "social" behavior, you may want to be able to use various Social subclasses as "plug-ins" inside User, rather than subclassing User.
Don't worry about memory so early. Go for readable/cleaner code. Premature optimization is root of all evil.
This is really based on the logic of your program. But consider that increasing the number of classes unnecessarily, is not good practice.
In your example, if the User class only contains a Social field, and you will just delegate all the method calls to the Social class, then go with scenario one.
On the other hand, if the User class has many more fields, like name, date of joining ... then it would be even better to create a separate class for such fields such as UserInfo in order to better structure your program and enhance code readability.
Now the main concerns are not the memory or performance costs of class structure.
Way more important are readability and clean code, AND the possibility to persist domain classes in a DB in the most simple and efficient way.
The later include composition or aggregation concern which is specific for different DB's.
You should care about the design aspects becoz with this you will have maintainable,scalable and readable code.
Now going by your example , i find second scenario as good case as it follows the SRP(Single Responsibilty Principle)
Don't worry about memory here as it wont make iota of difference here.
So do you want to do something like:
for(Connection connection : userSocialConnections ){
sendMessageTo(connection);
}
If so, then the method sendMessageTo would need to accept a connection (friend or ignored, basically a user) and probably if the runtype connection is ignored (or has blocked the user) then the sendMessageTo will return without sending a message polymorphically. This would require that in java that the IgnoredPeople And Friends are subtypes of something called as Connection(or people or anything you like; in fact, a connection is also a user - current or potential, isn't it?). This approach seems (to me) more like thinking in problem domain. Storing as two list inside user or inside social inside user does not matter much as long as they both (ignored and friends) have a common interface.
I would ask, what all other scenarios can be there for user's friends or ignored list. Do they need to be loaded lazily or stored separately.

Designing a point system in Spring

I have a lot of existing data in my database already, and want to develop a points mechanism that computes a score for each user based on what actions they do.
I am implementing this functionality in a pluggable way, so that it is independent of the main logic, and relies on Spring events being sent around, once an entity gets modified.
The problem is what to do with the existing data. I do not want to start collecting points from now, but rather include all the data until now.
What is the most practical way to do this? Should I design my plugins in such a way as to provide for an index() method, which will force my system to fetch every single entity from the database, send an EntityDirtyEvent, to fire the points plugins, for each one, and then update it, to let points get saved next to each entity. That could result in a lot of overhead, right?
The simplest thing would be to create a complex stored procedure, and then make the index() call that stored procedure. That however, seems to me like a bad thing either. Since I will have to write the logic for computing the points in java anyway, why have it once again in SQL? Also, in general I am not a fan of splitting business logic into the different layers.
Has anyone done this before? Please help.
First let's distinguish between the implementation strategy and business rules.
Since you already have the data, consider obtaining results directly from the data. This forms the data domain model. Design the data model to store all your data. Then, create a set of queries, views and stored procedures to access and update the data.
Once you have those views, use a data access library such as Spring JDBC Template to fetch this data and represent them into java objects (lists, maps, persons, point-tables etc).
What you have completed thus far does not change much, irrespective of what happens in the upper layers of the system. This is called Model.
Then, develop a rule base or logic implementation which determines, under what inputs, user actions, data conditions or for all other conditions, what data is needed. In mathetical sense, this is like a matrix. In programming sense, this would be a set of logic statements. If this and this and this is true, then get this data, else get that data, etc. This encompasses the logic in your system. Hence it is called "Controller".
Do not move this logic into the queries/stored procedure/views.
Then finally develop a front-end or "console" for this. In the simplest case, develop a console input system, which takes a .. and displays a set of results. This is your "view" of the system.
You can eventually develop the view into a web application. The above command-line view can still be viable in the form of a Restful API server.
I think there is one problem here to be considered: as I understand there's huge data in the Database so the idea to create only one mechanism to calculate the point system could not be the best approach.
In fact if you don't want to start collecting points but include all the data, you must process and calculate the information you have now. Yes, the first time you will run this can result an overhead, but as you said, you need this data calculated.
By other hand you may include another mechanism that attends changes in an entity and launches a different process capable of calculate the new pointing diffence that applies to this particular modification.
So, you can use one Service responsible of calculate the pointing system, one for a single entity and another, may be longer to finish, capable of calculate the global points. Even, if you don't need to be calculated in real-time you can create a scheduled job responsible of launch it.
Finally, I know it's not a good approach to split the business logic in two layers (Db + Java) but sometimes is a requirement do it, for example, if you need to reply quickly to a request that finally works with a lot of registries. I've found some cases that there's no other option than add business logic to the database (as a stored procedures, etc) to manage a lot of data and return the final result to the browser client (ex: calculation process in one specific time).
You seem to be heading in the right direction. You know you want your "points" thing decoupled from the main application. Since it is implied you are already using hibernate (by the tag!), you can tap into the hibernate event system (see here section 14.2). Depending upon the size/complexity of your system, you can plugin your points calculations here (if it is not a large/complex system), or you can publish your own event to be picked up by whatever software is listening.
The point in either design approach is that neither knows or cares about your point calculations. If you are, as I am guessing, trying to create a fairly general purpose plugin mechanism, then you publish your own events to that system from this tie-in point. Then if you have no plug-ins on a given install/setup, then no one gets/processes the events. If you have multiple plug-ins on another install/setup, then they each can decide what processing they need to do based upon the event received. In the case of the "points plugin" it would calculate it's point value and store it. No stored proc required....
You're trying to accomplish "bootstrapping." The approach you choose should depend on how complicated the point calculations are. If stored procedures or plain update statements are the simplest solution, do that.
If the calculations are complicated, write a batch job that loads your existing data, probably orders it oldest first, and fires the events corresponding to that data as if they've just happened. The code which deals with an event should be exactly the same code that will deal with a future event, so you won't have to write any additional code other than the batch jobs themselves.
Since you're only going to run this thing once, go with the simplest solution, even if it is quick and dirty.
There are two different ways.
One is you already know that - poll the database for for changed data. In that case you are hitting the database when there may not be change and it may slow down your process.
Second approach - Whenever change happens in database, the database will fire the event. That you can to using CDC (Change Data Capture). It will minimize the overhead.
You can look for more options in Spring Integration

Business rules Java app for User

The description may sound like just a bunch of words so here is a more detailed explanation. I have a User object which is mapped to database table.
I want users to be in different roles. There will be a bunch of those - and they technically will be the same users in same table but to them will apply different roles. Say user in role A will have to have two fields as required, and will have to have certain restrictions to the length and contents on his password, as well as the time expiration of his password, etc.
While I can hardcore those rules I am very interested to find out of there is an other way to define the rules and may be store in database so it's easier to load/apply and the main idea - to change and update them -- without redeploying the codebase.
Technically the stupidest and straightforward solution is to implement class, serialized, store in db, then load, deserialze, call methods on it which will execute rules. The problem is in changes to the ruleset ( read "interface" of the rule class ) and that generally solution sounds like a hack.
Anytihing else? Any frameworks? Other approaches?
UPDATE: probably was not clear. say, I have class User.java
I need to define different rules say:
1. do we need to verify length of password, and what should it be?
2. do we need to require some properties to be required?
3. do we need to track login attempts for this user?
4. if we do track, how many login attempts allowed?
5. do we expire password?
6. if we do, then in how many days? or months? or weeks?
7. ...
and so on and so on.
so questions ARE.
- how do I define those rules and operate on User object WITHOUT modifying and redeploying code base?
- how do I store those set of rules?
Drools, jBPM, etc. do not seem like a fit for that task. But any advice would help!
JRuleengine is good I heard, sometime back I planned to use it for similar application.
There are many other Rule Engines though.
Well there are some good rules engines out there include jrules, drools I think is popular too. One thing to keep in mind is the relationship between a rule and the data it examines. After all you can have the rules in a word document, but when they execute they need examine data, and that is also a factor in choosing a rule engine or architecture. generally its if (a > b) then do y. Means you need to examine a and b in the rule execution. That is the real issue is how to get the parameters into the rule and engine.

Some kind of Data persistency

Basically what I need to know is this:
I have to show a drop down list of countries to my users each country also has a code associated to it. I will have to work with both the country and the code What would be the best approach:
-We (the dev.) are thinking about a table in our app database with this data, or XML file.
-Our "architect" says that is old school and that we should use constants in our app with a map that associates the country with the code
Please Help me feel smart
I agree with you that you should not hard code this or use constants. There are a few good options depending on yours needs:
Java Properties Files - If you just have a few key-value pairs to store, these are the simplest way and easy to use.
XML Storage - If you are looking for persistence and are looking at XML for storage, I would recommend looking at JAXB. It is part of Java 6 and will make your life easier than trying to use the DOM.
Database Persistence - If you have more data that is changing often, you could also look at storing it in a database. JPA is a great standard library for doing this. That is probably overkill for what you are looking for though.
Bottom line is hard coding is a thing of the past. There are lots of great ways to get data in quickly and easily without resorting to hard coding everything.
Countries rarely change, so adding them statically as code or a config file seems reasonable. If you don't use a database for anything else, don't add one just for this feature.
If you already have XML parsing in your app, use an XML file to define the data. It already solves all kinds of issues (for example if you need to add a second attribute per country or something).
If you don't use XML for anything else, I suggest to give it a try. It doesn't add much to your app. Otherwise, use a plain text file, maybe a CSV one.
The different methods have different advantages and drawbacks:
Database:
allows you to use the country data in queries
data can be changed without redeploying the app
editing the data requires you to write some sort of frontend or do it manually via some generic SQL browser
requires database access code, and some sort of caching strategy
Any country-based logic in the code can break when the DB changes, or has to be reflected in the DB
XML:
Very easy to edit
can be changed without recompiling the app, but changes have to be deployed somehow
Requires parsing code and some sort of caching strategy
Any country-based logic in the code can break when the XML changes, or has to be reflected in the XML
Code:
Easy to edit - for developers
Changes require compilation and deployment
Requires no extra technical layers
Code and country data can't get out of synch
All in all, the "code as data" solution is indeed the nicest, if the compile&deploy step for each change is acceptable to you. The other solutions create overhead and duplication of structure (or even logic) - and no, they don't magically make it "safe" to do last-minute changes "because it's not code". Code is data, and data is code.
In short your architect is wrong (Or at least he is if your paraphrase of his position is accurate). It shouldn't be in the code.
This data is not static; a country's name changes, a new one is founded, or some cease to exist.
As far as what mechanism, it doesn't necessarily matter. Just make sure you can retrieve the data easily, that you have unit tests, and that there is straightforward mechanism to update the data.
I think that "table solution" has more flexible approach:
1. You can manage data and connecting properties
2. You can work with table directly
3. You can create associated map, based on db table))
I would certainly not use them as constants in the code.
Names can change, while countries can be created, merge, disappear, etc.
If you are already using a database, adding this may make sense. For one, it ensures that the codes that may be stored with client data are valid in terms of your country code list. So if a country disappears but a client record still refers to it, the data stays valid.
Make sure that your UI loads and caches the list; no point making a query every time if you can avoid it.
By the way, correctly handling countries in an internationalized application is much more complicated than just dealing with renames. For example, if a country or part of a country declares independence, some countries will recognize it, while others do not.

Categories