I have following table names with plural definition. But my classes are singular named.
E.g.
Table-Name: Employees
Java-Classname: public class Employee {
Additionally our code convention defines the rule, that all member fields/variables have to have the prefix m_salery
e.g.
ColumnName: Salery
Java-Fieldname: m_salery
Now my questions:
What is the standard way in JPA 2.1 to define a default tablename strategy and a columnNmae strategy for the naming? If I need to define all java-fields and Entity-Annotations manually, I will go crazy.
JPA does not offer any globally applicable strategies for templating table/column names. Unfortunately, due to your code conventions, you are going to have to specify table names and column names manually using JPA annotations like #Table(name=...) and #Column(name=...).
It seems appropriate to avoid these code conventions here.
Code conventions are generally put in place to improve the readability of source code and make software maintenance easier. In this particular case, the conventions are not improving either case.
Related
Me and my team are building java EE app as a school project and we've decided to use hibernate. We also want to make the whole project as nice and clean as possible, so we're trying to follow recommended conventions. Nevertheless I wasn't able to find out, what are the conventions for hibernate files.
I.E. I've got a folder /cz/fit/cvut/nameofmyproject/ and there I've got packages controllers, models, utils. In controllers I've got Spring controllers, in models I want to have models for my entities and in utils I've got SessionFactory for hibernate. And now my question:
How shall I name classes in model package? Should it be MyEntityNameDTO, or did I misunderstand the meaning of the DTO and should I just name them MyEntityNameModel? And what should be the proper name for the folder for my DAO classes? Will this simple division be enough for a middle-size project (max ~20 classes/folder) or would it be too confusing? Thanks for any tips from praxis :)
DTO stands for Data Transfer Object. A DTO is a class which is more a data structure than a real class, usually, and which is created to transfer information from one layer to another, often across the network. It's not a model entity.
A DTO is often used
when serializing real model objects is not paractical (because the structure doesn't fit, or because the receiver doesn't have access to Hibernate classes, or because lazy-loaded entities are a problem)
when you want to transfer information that is an aggregation, or a complex view, over your model objects (like data of a statistical report for example)
So naming your entities DTO is not a good idea. DTOs and entities are different things. The Model suffix is also cumbersome. Entities are usually named after what they represent: Customer, Company, Player, Order, etc.
Segregating classes based on their technical role is an often used solution. But it tends not to scale when the application grows. I usually have a first level of segregation based on a functional aspect (like customer management, order management, security, etc.), and then a second level based on technical aspects (service, dao, model, etc.)
UserDAO - interface
UserDAOImpl - implements UserDAO
That is generally what I use. Sometimes the Default prefix like DefaultUserDAO might make more sense if you're creating an interface that you expect others to implement but you're providing the reference implementation.
Most of the time I feel those two can be used interchangeably but in some situations one provides a little more clarity than the other.
There are two conventions that I've seen:
FooDao for the interface and FooDaoImpl for the implementation
IFooDao for the interface and FooDao for the implementation
The former has its roots in CORBA; the latter is a Microsoft COM/.NET convention. (Thanks to Pascal for the correction.)
Hibernate provides the Naming Strategy interface to be implemented by the implementation.
I am listing here few methods.
String classToTableName(String className) – should return the table name for an entity class.
String columnName(String columnName) – handle to alter the column name specified in the mapping document.
String tableName(String tableName) – handle to alter the column name specified in the mapping document.
String propertyToColumnName(String propertyName) – handle to map property name to column name.
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.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
In Java the naming convention for properties en classes (entities) are done the CamelCase way:
#Entity
public class UserMessage implements Serializable {
#Id
private Integer id;
private String shortTitle;
private String longTitle;
private String htmlMessage;
}
But in the SQL world it’s considered a best practice to use upper case with underscores between words (like Java constants). In the SQL world is also considered a best practice to include the table name in the column names, this way foreign keys are in most cases named exactly the same as the id in the original table.
CREATE TABLE USER_MESSAGE (
USER_MESSAGE_ID MEDIUMINT(8) NOT NULL,
USER_MESSAGE_SHORT_TITLE VARCHAR(20),
USER_MESSAGE_LONG_TITLE VARCHAR(80),
USER_MESSAGE_HTML_MESSAGE TEXT NOT NULL
);
Should I follow both standards and use the name attribute on #Table and #Column? Or should I follow the Java conventions and rely on the default JPA mappings.
What is the most common approach and/or the best approach on this conflict of standards?
Should I follow both standards and use the name attribute on #Table and #Column? Or should I follow the Java conventions and rely on the default JPA mappings.
If the JPA default conventions don't match the preferred conventions of your company (there is no "one true" standard), override them. This can be done using the #Table and #Column annotations (in the particular case of Hibernate, you could also provide your own implementation of a NamingStrategy).
What is the most common approach and/or the best approach on this conflict of standards?
There is no conflict, there are Java naming conventions, there is one default convention on the JPA side for the mapping of objects to tables (because JPA had to pick one) and there is no "one true" standard on the SQL side. So:
if your company doesn't have any SQL naming conventions, you could use the JPA conventions
if you don't like them, override them
if your company has conventions in place, follow them and override the JPA defaults
I suppose that this depends on whose conventions you're referring to. I do not put the table name into the column name - what's the point of losing half your namespace just to repeat what you already know? (Some of) the rules I (try to) follow are:
Long, meaningful names are better than short names, e.g. TRANSACTION_DATE rather than TRAN_DT. Yes, I'm old enough to have written Fortran when you were limited to 6-character variable names, and I recall Basic variants where you only had A-Z, A0-Z0...A9-Z9 - but I'm also old enough to have learned better. Single-character variable names for indices, etc, are fine - and in fact traditional - but when I find a function with twelve single-letter variable names each used for multiple purposes I...am not amused.
Artificial primary keys are named ID_<<"name of table">>.
Single-field natural data primary keys are best. Two-field natural primary keys are OK. Three or more fields - create an artificial primary key and make the natural key an alternate unique key.
Thou shalt never, ever, ever count on a date, time, or date/time field to be unique. Ever. Don't forget this. I mean it.
Obfuscatory coding techniques are equivalent to incompetence.
I'm sure there's more, but it's a start. All IMHO. YMMV.
Share and enjoy.
Follow both. The db convention should be there for DBA sake and manual reports and queries where the mind set is different. Use the name params on annotations to achieve this.
As far as I'm concerned either are acceptable. But if you decide you don't want the default camel case, you CAN get a different naming strategy without resorting to the tedious and error-prone task of adding the name attribute to every annotation.
Take a look at Hibernate's org.hibernate.cfg.ImprovedNamingStrategy class. It uses underscores instead of camel case. It is simply a matter of setting a property on your Hibernate configuration to use it.
You could also extend the ImprovedNamingStrategy to prepend the table name or do all uppercase if you really want, but that seems unnecessary.
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.
I am mapping my database tables to my java objects. Generally I name my tables in the plural form in that a table holding books information is called BOOKS. The java object represents however one book and should be called Book. Similarly for AUTHORS/Author etc.
On the other hand, its kind of simplistic to give the same to the domain object and the table.
Is there some kind of naming convention that people follow? I guess this applies to applications in general and not just while doing O/R mapping.
Your initial thoughts are spot on.
Objects should be singular, as each object is individual.
Tables should be plural, as the table contains all.
Check out the naming conventions built into Ruby on Rails, they're relevant.
We use singular for table names and for OM classes. It makes more sense, to me, to say
person.last_name
than
people.last_name,
whether I'm writing SQL or Java (where, of course, it would be person.lastName, but you get the point).
I use SubSonic in my ASP.NET application, and I have it strip the plurals when naming the ActiveRecord classes. It's more a matter of style than a standard.
I prefer working with Invoice rather than Invoices because I'm usually dealing with 1 record at a time.
I usually just make sure i use the same standard everywhere, and also that i use logical names for my namings.
So Books become something like DbBooks, Authors becomes DbAuthors etc.
CJ Date does not use Plural names and neither should you. The only exception is the word "SALES". Other than that, use singular names.
compare
user.email = ? and account.value in (1,2,3)
to
users.email = ? and accounts.value in (1,2,3)
or (the worst option)
users.email = ? and account.values in (1,2,3)
jOOQ generates Java classes from your database schema. The classes modelling the tables will be called the same as the table itself, e.g.
AUTHOR > Author
BOOKS > Books
The classes modelling the objects (or records) will be suffixed with "Record":
AUTHOR > AuthorRecord
BOOKS > BooksRecord
That's pretty intuitive and generic, no matter what your tables are called. See
http://www.jooq.org