Is there a standard naming convention for DAO methods, similar to JavaBeans?
For example, one naming convention I've seen is to use get() to return a single entity and find() to return a List of entities.
If there isn't one, what's the one your team is using and why?
I am aware of conventions like the following:
methods starting with find perform select operations, and method names containing the search criteria, like findById, findByUsername, findByFirstNameAndLastName, etc.
modification methods start with create, update, delete.
Check out the conventions used by Spring Data JPA. This is part of the Spring framework that writes the DAOs automatically based on among other things inspection of the method name based on naming conventions.
get() for single entities does not seem to be a good option, as get is associated by Java developers to a Java-bean getter.
Usually I name the methods in such way that the name hints the type of the CRUD operation that will be applied by the method, like add*, save* or find*.
add* can be applied on INSERT operations, like addPhoneNumber(Long userId).
get* can be applied for SELECT operations, like getEmailAddress(Long userId).
set* can be applied on method that performs an UPDATE operation.
delete* can be applied on DELETE operations, like deleteUser(Long userId). Althought I'm not pretty sure how useful is the physical delete. Personally, I would set a flag that denotes that the row is not gonna be used, rather than performing a physical delete.
is* can be applied on a method that check something, for example isUsernameAvailable(String username).
Related
I am building a small Java web application using Spring MVC, Hibernate and I am confused about the DAO classes methods naming.
For example I have an InvoiceDAO.java class which I thought should contain the following methods:
Save(Invoice newInvoice);
Void(Invoice oldInvoice);
getInvoiceByID(Long invoideID);
but my boss says that best practices says that I should have methods names in DAO classes as follows:
add(Invoice newInvoice);
update(Invoice oldInvoice);
which makes no sense for me as I am not sure how I can name voiding an invoice as Update?!!
So can someone please guide me in this and tell me if I am wrong on my methods naming? In other words is it correct that I should only use add, update for naming or can I use any naming and still be considered as best practices.
thanks
Voiding an invoice is a business operation. I would say such logic lives in your service layer. You make updates to the invoice to mark it as void, and then pass it to the data layer to save.
The data layer should contain pure CRUD type methods, that is add/save/find.
Using many modern data frameworks, you don't even need to write the data layer ... e.g. see http://blog.springsource.org/2011/02/10/getting-started-with-spring-data-jpa/
I've found this refeernce some time ago about DAO naming ...
Names according to function
getData* Data Parsing Methods used internally in DAO, do not use this namespace for data accessing.
get* (e.g. getUsersByID) SELECT queries – It is encouraged that you try to use the noun in Singular or Plural according to single or multi-row return.
set* (e.g. setActive) UPDATE Queries
add* (e.g. addUser) INSERT Queries – It is encouraged that you try to use the noun in Singular or Plural according to single or multi-row insert.
delete* (e.g. deleteUser) DELETE queries
is* (e.g. isActive) IF check returns boolean, i.e., if ($user_dao->isUserActive($id)) or if ($post_dao->isPostInStorage($id))
count* (e.g. countUsers) Returns integer with the item count.
Reserved functions
insert – takes an object as argument, and inserts it to the table.
save – takes an object as an argument, and stores the data in it back to data backend
poke – Takes an ID as argument, “pokes” the record (sets “last seen” or whatever to now), returns update count (usually 1)
Other things to remember
As the storage Backend may or may not be a “database”, it would be encouraged not to create methods with names that imply that the backend is using a database.
First of all, in Java, at least, you name your methods with the first letter of each internal word capitalized, camel-case. You can see at the section Methods this: Java Naming Conventions
Regarding the specific naming of your methods inside the dao:
I would go by creating basic crud operations that can be performed to your model classes
Example:
add(Invoice invoice)
update(Invoice invoice)
// or instead
save(Invoice invoice) // which will perform either add or update
delete(Invoice invoice) // or delete(int invoiceId)
findById(int invoiceId)
// and so forth
I would not make use of the term "void" inside the dao, since that is related to the business. Do the dao as simple as possible and after that in your service that will be using the dao, you can name your methods related to the business required (i.e. voice(Invoice invoice))
There is another possibility to create a generic dao with the basic CRUD operations and maybe you can then start naming the methods as you want:
public class InvoiceDAO inherits GenericDao<Invoice> {
// all the above methods would be inherited
// add specific methods to your dao
}
Again, if I were you I would move the naming of specific stuff in the service.
Now it's up to you how you want to approach from what I showed. The idea is to keep the dao as simple as possible.
You might as well go and name your void method (since you can do name it void, since in Java is a keyword -- thanks #Marco Forberg for noticing that) either delete (Void - means that it is deleted.) or performVoid. Or go simple with update if you are not removing the invoice from the database after you void it. update can be applied to any changes you made for your invoice entry.
Save and add have 2 different meanings. As do Void and update. Use the term that accurately describes what the method is doing. Im not aware of any specific best practise here.
Also, I would tend to only pass an ID into a void method if that is enough to perform the action. This is different scenario from an update where you may expect to update multiple attributes on the invoice.
One of my goals is to create an engine that will set values in pojo object from JPA objects dynamically using reflection. One of the matching criteria is, that the field names should match.
I was successfully able to implement this for two pojo objects. But when I tried using JPA objects as one of the object parameter, it didn't work. Based on my research I found out that the method Class.getDeclaredFields() , does not give me the name of the field but the getter/setter method name of member variable for JPA objects.
Can anyone please give me a lead or direction as in where/what should I look to accomplish this task?
JPA providers will often use dynamic proxy classes of your concrete JPA classes, so you have no guarantee of the field names in the proxy. The only guarantee about a proxy is that the methods are the same. Use a debugger to inspect the runtime class of the JPA class instances that you're trying to use and you'll see the problem.
The best you'll be able to do is use reflection to call methods on JPA-returned objects.
All that aside, I don't really see why you'd need to POJO-ify an entity class anyway, since an entity is primarily an annotated... POJO.
One of the matching criteria is, that the field names should match.
I think that this is the root of your problem. There is simply no guarantee that a Java object's field names will match the names of getters and setters ... or anything else. If you make this assumption, you will run into cases where is doesn't work.
The best solution is to simply not use this approach. Make it a requirement that the Pojo classes conform to the JavaBeans spec and rely on the setters to set the properties. This is likely to work more often than making assumptions about (private) field names.
In fact, the state of a generic JPA object implemented using a dynamic proxies could well be held in a hash map. Those fields you can see could simply be constants used for something else.
When creating named queries in JPA, is there an accepted best practice for the names of these queries (eg. EntityName.allActive or findAllActiveFoos etc.) and also is it good to declare these named queries in the entity classes that they query or all together in a utility class?
No, there is no widely accepted best practice that covers any complex cases. Also in general there is not too much style guides available for JPA. What seems to be commonly accepted, and in general used in books as well, is to start query with name of the entity.
I would go for EntityName (to guarantee unique names in persistence unit) combined with operation and arguments.
Person.findByAge
Person.findByAgeAndFirstName
Person.removeByFirstName
Person.updateSalaryIfYearBornBefore
Just as a note, specification uses with instead of by in examples, and does not prefix query with name of the entity. But that is of course specification, not style guide.
I find it good to declare constants for these query names and then use these constants in both #NamedQuery.name and em.createNamedQuery.
Because #NamedQuery, #NamedNativeQuery, and #NamedQueries can only be applied to mapped superclass or entity, you cannot locate them to utility class.
Although there doesn't seem to be a globally accepted best practice, the book "Pro JPA 2" by Mike Keith and Merrick Shincariol recommends exactly what Mikko said, e.g. if you have a query for finding all Employees then call it "Employee.findAll".
Ito where to declare these, again there is no real best practice from what I can see. They seem to tend to favour declaring them on the Entity itself rather than all in one big class (such as a base MappedSuperclass from which all your entities extend) since that would very quickly become monolithic and could be a bit hard to maintain. Another option is to declare them in a separate XML file, not that I would recommend that. Personally I like the approach where they are declared on the Entity that they are related to. I also agree with Miko's suggestion to use constants for the name, you could just define all of these constants in a separate class.
I'm working on a project where we use Hibernate and JBoss 5.1. We need our entity classes to be mapped to Oracle tables that follow a certain naming convention. I'd like to avoid having to specify each table and column name in annotations. Therefore, I'm currently considering implementing a custom implementation of org.hibernate.cfg.NamingStrategy.
The SQL naming conventions require the name of columns to have a suffix that is equivalent to a prefix of the table name. If there is a table "T100_RESOURCE", the ID column would have to be named "RES_ID_T100".
In order to implement this in a NamingStrategy, the implementation would have to maintain state, i.e. the current class name it is creating the mappings for. It would rely on Hibernate
to always call classToTableName() before propertyToColumnName()
and to determine all column names by calling propertyToColumnName() before the next call to classToTableName()
Is it safe to do that or are there situations where Hibernate will mix things up? I am not thinking of problems through multiple threads here (which can be solved by keeping the last class name in a ThreadLocal) but also of Hibernate deliberately calling this out of order in certain circumstances. For example Hibernate asking for mappings of three properties of class A, then one of class B, then again more attributes of class A.
That sounds like a really bad idea. Subverting the a stateless interface like that is almost certainly going to end in tears, because as you say, there's no guarantee at all that Hibernate will call things in the right order.
I'm surprised at this naming convention, though, especially when you consider that Oracle has a hard-wired 30 character limit on identifiers. It can be hard enough trying to come up with good names that fit, without worrying about having the table name prefixing every column name. This certainly isn't an Oracle naming convention I've ever come across, it's just wasteful.
My Java (JDK6) project uses Spring and JDBCTemplate for all its database access. We recently upgraded from Spring 2.5 to Spring 3 (RC1). The project does not use an ORM like Hibernate nor EJB.
If I need to read a bunch of records, and do some internal processing with them, it seems like there are several (overloaded) methods: query, queryForList and queryForRowSet
What should be the criteria to use one instead of the other? Are there any performance differences? Best practices?
Can you recommend some external references for further research on this topic?
I find that the standard way to access as list is via the query() methods rather than any of the other approaches. The main difference between query and the other methods is that you'll have to implement one of the callback interfaces (either RowMapper, RowCallbackHandler, or ResultSetExtractor) to handle your result set.
A RowMapper is likely what you'll find yourself using most of the time. It's used when each row of the result set corresponds to one object in your list. You only have to implement a single method mapRow where you populate the type of object that goes in your row and return it. Spring also has a BeanPropertyRowMapper which can populate the objects in a list via matching the bean property names to the column names (NB this class is for convenience not performance).
A RowCallbackHandler is more useful when you need your results to be more than just a simple list. You'll have to manage the return object yourself you are using this approach. I usually find myself using this when I need a map structure as my return type (i.e. for grouped data for a tree table or if I'm creating a custom cache based of the primary key).
A ResultSetExtractor is used when you want to control the iteration of the results. You implment a single method extractData that will be the return value of the call to query. I only find myself using this if I have to build some custom data structure that is more complex to build using either of the other callback interfaces.
The queryForList() methods are valuable in that you don't have to implement these callback methods. There are two ways use queryForList. The first is if you're only querying a single column from the database (for example a list of strings) you can use the versions of the method that takes a Class as an argument to automatically give you a list of only objects of those classes.
When calling the other implementations of queryForList() you'll get a list back with each entry being a map of for each column. While this is nice in that you are saved the expense of writing the callback methods, dealing with this data structure is quite unwieldy. You'll find yourself doing a lot of casting since the map's values are of type Object.
I've actually never seen the queryForRowSet methods used in the wild. This will load the entire result of the query into a CachedRowSet object wapped by a Spring SqlRowSet. I see a big downside in using this object in that if you're passing the SqlRowSet around to the other layers of your application, you're coupling those layers to your data access implementation.
You shouldn't see any huge performance differences between any of these calls except as I mentioned with the BeanPropertyRowMapper. If you're working with some complex manipulation of a large result set, you might be able to get some performance gains from writing an optimized ResultSetExtractor for your specific case.
If you want to learn more I would consult the Spring JDBC documentation and the JavaDoc for the classes I've mentioned. You can also take a look at some of the books on the Spring Framework. Though it's a bit dated Java Development with the Spring Framework has a very good section on working with the JDBC framework. Most of all, I would say just try writing some code with each method and see what works best for you.
Since you are in the wonderful Generics land, what you may really want to do is to use SimpleJdbcTemplate and use its query() methods for Lists of objects and queryForObject() for individual objects. Reasoning for this simply is that they're even easier to use than the ones in JdbcTemplate.
One small addition to the excellent answers above: additional methods, like queryForInt, queryForLong, queryForMap, queryForObject, etc. might seem like good options at times if you're running a simple query and expect a single row.
However, if you could get 0 or 1 rows back, the queryForList method is generally easier, otherwise you'd have to catch IncorrectResultSizeDataAccessException. I learned that the hard way.