Globally set default 'nullable=false' for #Column definition - java

From #Column annotation documentation i verified nullable attribute has true as default value.
In my entities definitions I'd like to set columns non-nullable as default behavior, but I don't want to set this for every single column.
Is there a way to globally change default value for nullable attribute (and eventually others)?

JPA takes the nullable property from the tables on your database if the columns on your table were notnull then your entity attributes would be #NotNull too. You could do the changes on your database and recreate the entities.

I'm not familiar with a way to override JPA default settings, but you could use EntityListeners to perform some #PrePersist validations and check that an object fields (non transient ones) are not null by reflection.
Having said that, I believe that this makes the entity definition less clear and would rather stick to the more declarative technique using (nullable="false").

Related

Setting default values for columns in Hibernate during query mapping

#Column (name="AMOUNT")
private BigDecimal amount;
I saw many answers in Stackoverflow, the solution is either using columnDefinition or set the default value in Java contructor.
But what I need is for data query, not table creation or data insertion. When I use hibernate session to query out the object, and call the method getAmount(), it will return null BigDecimal Object, which I want to set the default value to 0 BigDecimal.
How can I do that since the mapping is done by Hibernate framework?
You have several options:
Use a #Transient getter method. In this case, you may want to mark the getter for the amount field as protected or private (Hibernate won't care) and then expose a special public method that is annotated with #Transient that performs the translation for you.
Use a #PostLoad annotated method event callback to translate the value rather than a #Convert. You'd likely want to leverage part of #1 where you add a new property that stores the translated value you calculate in the post load callback and then annotate the field or getter with #Transient.
Use an attribute converter if you can leverage JPA 2.1. In this case, you would annotate the field with #Convert and specify a converter class implementation that translates a null value to 0.
The benefit of the first two options is that you don't need to be concerned with how to map values back to the database column (e.g. does 0 translate to a NULL at the table level).
From a performance perspective, if amount is accessed numerous times, I'd probably use #2 personally and cache the value after having translated it once.

#NotNull on default in JPA/Hibernate

I have MySql database with several tables. Every field in each table is not nullable. That's why I am forced to use #NotNull annotation to each field in all my Java classes marked with #Entity. Do I really have to do this or is there a way to tell JPA/Hibernate to treat every field NotNullable on default?
edit:
I am aware of #Column(name="something", nullable=false) too. But still, it doesn't solve any problem - you have to write nullable=false
There are no such possibility. Not Nullable constraint is not what you always expect from a field, although it is used quite often. It is convenient when you can look at the attribute definition and tell everything out of it, without addressing to some high-level settings like "every field should be #NotNull".
It would be rather confusing to see such entity definition with this setting hidden elsewhere.
And, one more thing. #NotNull annotation and #Column(name="something", nullable=false) are not the same. More details here :
Confusion: #NotNull vs #Column(nullable = false)

Adding a constraint to a JPA or Hibernate entity column using annotations

I want to have a column for an entity which only accepts one of an enumerated set of values. For example let's say I have a POJO/entity class "Pet" with a String column "petType". I want petType to only allow one of three values: "cat", "dog", or "gorilla". How would I go about annotating the getPetType() method in order to have a database level constraint created which enforces this?
I am allowing Hibernate to create or update my database table at application start up via the Hibernate property "hbm2ddlauto" being set to "update".
I have tried using a parameterized user type in association with the #Type annotation but this doesn't appear to provide any sort of constraint on the database column itself. There doesn't appear to be a way of specifying this sort of constraint in the #Column annotation short of using some SQL with the columnDefinition element, and I'm hesitant to go this route since it seems that whatever I use there will not be cross platform/database independent (important to me since I run my code in production on Oracle but I do testing locally using HSQLDB and Derby). Maybe what I want to do just can't be done simply using annotations.
Thanks in advance for any insight you can give me on this topic.
Create a enum of type PetType and defined you mapping as
#Enumerated(EnumType.STRING)
That way, strings are stored in the database and your java enum type only accept the 3 values you specify.

What is the difference between #ManyToOne(optional=false) vs. #Column(nullable=false)

In JPA, I am confused when to use the attribute optional=false and the annotation #Column(nullable=false). What is the difference?
#Column(nullable=false) is an instruction for generating the schema. The database column generated off the class will be marked not nullable in the actual database.
optional=false is a runtime instruction. The primary functional thing it does is related to Lazy Loading. You can't lazy load a non-collection mapped entity unless you remember to set optional=false (because Hibernate doesn't know if there should be a proxy there or a null, unless you tell it nulls are impossible, so it can generate a proxy.)
Both is used to prevent a null value, but if you mind that null should be blocked in ...
The database layer (and you want to generate the schema using JPA) --> use #Column(nullable=false)
The runtime (and before contacting the database)--> use optional=false (much faster than the first checking).
If you want both abilities, use them both.

The difference between annotating fields and methods in JPA (Hibernate)?

Are there any statements in JPA spec or official docs about certain JPA implementations which describe the behavior when we annotate entity's methods and when we annotate entity's fields?
Just a few hours ago I met an ugly problem: I use JPA (via Hibernate, but without anything Hybernate-specific in java code) with MS SQL Server. And I put all annotations on entities' fields (I preferred this style until this day).
When I looked at the DB I found that all table columns which should be foreing keys and which should contain some integers (ids) in fact had varbinary(255, null) type and contained hashes of something (I don't know what was that but it looked as a typical MD5 hash).
The most frustrated thing is that the app worked correctly. But occasionally (on updates) I got MS SQL exception which stated that I tried to insert too long values and data cannot be truncated.
Eventually (as an experiment) I removed all annotations from entities fields and put all of them on methods. I recreated DB and all tables contained perfect FK column. And those columns stored integers (ids, like 1, 3 ,4 ...).
So, can somebody explain what was that?
I've found this SO thread and it's accepted answer says that the preferred way is to put annotations on fields. At least for my concrete case I can say that it's not true.
JPA allows for two types of access to the data of a persistent class. Field access which means that it maps the instance variables (fields) to columns in the database and Property access which means that is uses the getters to determine the property names that will be mapped to the db. What access type it will be used is decided by where you put the #Id annotation (on the id field or the getId() method).
From experience, I do the following.
I put the entity details at the top of the entity class definition, (schema, row constraints, etc) for instance....
#Entity
#Table(name="MY_TABLE", schema = "MY_SCHEMA", uniqueConstraints = #UniqueConstraint(columnNames = "CONSTRAINT1"))
For the fields defined, I do not put the annotations on the field declarations, but rather on the getter methods for those fields
#Column(name = "MY_COL", table="MY_TABLE", nullable = false, length = 35)
public String getMyCol() {
return this.myCol;
}
public void setMyCol(String myCol) {
this.myCol = myCol;
}

Categories