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.
Related
This question already has answers here:
Which annotation should I use: #IdClass or #EmbeddedId
(7 answers)
Closed 2 years ago.
what's better for JPA/Hibernate composite primary keys, #IdClass or #EmbeddedId implementations and why?
This is an intentionally naive question. I decided to use #EmbeddedId (for whatever reason) and I feel like I made the wrong choice. Dereferencing the embeddedId that contains the column properties is redundant and quite error-prone when coding.
Are there any more reasons for and/or against the other? Is the a recommendation by the JPA (spec)?
First, if possible, avoid composite ids at all costs. But if you really need, I would recommend #EmbeddedId.
#IdClass is basically a leftover from EJB 2.1 times to make it easier from migrating from BMP. In some other rare corner cases it may be better than #EmbeddedId too. However, generally #EmbeddedId is better and more OO since it encapsulates the concept os the key much better in the object.
You may want to use #AttributeOverride(s) if you need in the key field.
I don't see why do you think that dereferencing the embedded id is redundant and error-prone.
As Pascal wrote here's part of the answer:
Which annotation should I use: #IdClass or #EmbeddedId
In the end, I believe using #IdClass is much easier in practice, because you have to add the embeddedId property name to dereference PK properties, while these aren't written for all non-PK properties.
You always have to remember exactly which properties are part of a PK and those which are not. That complicates writing JPQL queries unneccessarily.
Also, AFAIK the JPA 2.0 spec allows you to put #Id onto #XToX/#JoinColumn/s properties and it introduces the #MapsId annotation, so that mapping identifying relationships (a.k.a. derived identifiers in JPA) are more natural to implement.
I. Remember using idclass to do it. But I'd recommend doing everything you can to avoid multi field keys. They just create extra work.
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.
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.
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