How to configure "hibernate-mapping" to "field" - java

I want to specify via standard JPA Persistence.createEntityManagerFactory(String,Map<String,String>) to hibernate to use "hibernate-mapping" to "field" rather than "property".
How can I do this, the clean way?

JPA determines which mapping type to use based on where you put your #Id annotation. So if you put your #Id annotation on a field then the mapping will be field-based.
UPDATE:
In JPA 2.0 You can also use the #Access annotation. You can apply it to the class to specify the access type for the entire entity and you can apply it to individual fields/methods to override the default for a single field/property.

Related

What are the default JPA annotations

I am working on a project that uses JPA and hibernate, and I've just noticed that the entities don't have any relationship annotations such as #ManyToOne, #OneToOne, etc.
So my question is, does JPA/Hibernate adds a default annotation for each case?
Here is an examples
#Entity
#Table(name = "strategy")
public class Strategy extends TradingEntity implements Serializable {
...
#Valid
private List<Rule> rules;
Does JPA add a #OneToMany annotation by default to this property ?
There are no "default" annotations, but some JPA implementations (e.g the one I've been using, DataNucleus) are intelligent enough to work out that if a field is a Collection of an Entity type then it is a OneToMany/ManyToMany and to default things like fetching and cascading etc. Clearly you cannot assume that your implementation will have this logic so should put what you need (and "JPA" does nothing, it is your implementation that would do it). Clearly also, you can specify the same info in XML so could have no annotations

Is there a way to declare #Convert directly onto the ENUM

I am using #Convert(converter = CoverConverter.class) to convert attribute value before storing it on a database and vice versa. I have to declare this annotation at each an every place where I am using a particular ENUM. Let's call it TestENUM for now.
But this particular ENUM is used at more than 100 places and I am not sure that other developers in my group will remember to add this annotation when they use this ENUM.
So I was wondering if there was a way that I can annotate an ENUM directly in a way that wherever it is used it will be converted before being persisted into database and vice versa when fetched from database through JPA
so example:
#Convert(convert = true)
public enum TestENUM {}
You should be able to create a Converter and use the autoApply property:
If the autoApply element is specified as true, the persistence
provider must automatically apply the converter to all mapped
attributes of the specified target type for all entities in the
persistence unit except for attributes for which conversion is
overridden by means of the Convert annotation (or XML equivalent).
http://docs.oracle.com/javaee/7/api/index.html?javax/persistence/Convert.html
#Converter(autoApply = true)
public class MyEnumConverter implements Converter{
}

Hibernate mapping Interface with multiple targetEntity

I am trying to develop an application with Hibernate and javax.persistence Annotations. I have some troubles in mapping an interface.
I have mapped my interface as #MappedSuperclass and I have already tried to use the attribute targetEntity in my ManyToOne Annotation that referred to the interface and it worked.
The problem is that I would more than one class to act as targetEntity. In particular I'd like that every class that implements my interface, could be recognized as a target entity.
Does anybody knows if it's possible to do it?
I think this
In particular I'd like that every class that implements my interface,
could be recognized as a target entity.
is not possible. Only classes which are annotated with #Entity or which are mapped in an other way (for example with a mapping file) can be persisted.
Also, the Hibernate documentation says:
Note
Annotating interfaces is currently not supported.
See the rather old question Interfaces with hibernate annotations for additional information.

is it possible to make all fields of an object #Transient by default

I have a base Entity class which will be derived in more than a hundred of a subclasses.
In order to be sure that persisted fields will be the ones I want (and not the users of that base class), I want to declare this JPA entity as setting all fields as transient by default.
How is it possible ?
If you don't put #MappedSuperclass on your class you are extending from, the class properties will never by persisted.
You can provide getter methods for certain properties, and place the annotations on the properties instead of the fields. The #Id annotation determines if you want the fields or the properties. In JPA 2 you can also use the #Access annotation.

Where to put hibernate annotations?

Where do i put my hibernate annotations?
Is it the line above my instance variable? Or before the getter? Or before the setter? Or doesn't it really matter?
Thanks a lot
You place them either on the field or on the getter. From the Hibernate Annotations Reference Guide:
2.2.1. Marking a POJO as persistent entity
(...)
Depending on whether you annotate
fields or methods, the access type
used by Hibernate will be field or
property. The EJB3 spec requires that
you declare annotations on the element
type that will be accessed, i.e. the
getter method if you use property
access, the field if you use field
access. Mixing annotations in both
fields and methods should be avoided.
Hibernate will guess the access type
from the position of #Id or
#EmbeddedId.
You might also want to read about the #Access annotation that allows to force/override the access type (prior to Hibernate Annotations 3.5 and JPA 2.0, it was part of Hibernate Annotation Extensions):
2.2.2.2. Access type
By default the access type of a class
hierarchy is defined by the position
of the #Id or #EmbeddedId annotations.
If these annotations are on a field,
then only fields are considered for
persistence and the state is accessed
via the field. If there annotations
are on a getter, then only the getters
are considered for persistence and the
state is accessed via the
getter/setter. That works well in
practice and is the recommended
approach.
Note
The placement of annotations within a class hierarchy has to be consistent
(either field or on property) to be
able to determine the default access
type. It is recommended to stick to
one single annotation placement
strategy throughout your whole
application.
However in some situations, you need
to:
force the access type of the entity hierarchy
override the access type of a specific entity in the class hierarchy
override the access type of an embeddable type
The best use case is an embeddable
class used by several entities that
might not use the same access type. In
this case it is better to force the
access type at the embeddable class
level.
(...)
Regarding the pros and cons of both styles, I suggest to read the following questions:
Hibernate/JPA - annotating bean methods vs fields
Hibernate Annotations - Which is better, field or property access?
Performance difference between annotating fields or getter methods in Hibernate / JPA
It's up to your style. You may put it before the field or before getter. In strict JPA, the annotations on setters are ignored, but I'm not sure if Hibernate follows that.
You either need to be consistent throughout your Entity, or you need to provide an #Access annotation at the top of the class with a default mode, and another #Access before each field/property you wish to deviate from the current class mode.
Hibernate is known to use Java reflection. So it really doesn't matter whether you put it above the filed or above the getter.
Here is the description of some important annotation used in Hibernate.
#Entity: declares the class as an entity (i.e. a persistent POJO class)
#Table: is set at the class level; it allows you to define the table, catalog, and schema names for your entity mapping. If no #Table is defined the default values are used: the unqualified class name of the entity.
#Id: declares the identifier property of this entity.
#Generated Value: annotation is used to specify the primary key generation strategy to use. If the strategy is not specified by default AUTO will be used.
#Column: annotation is used to specify the details of the column to which a field or property will be mapped. If the #Column annotation is not specified by default the property name will be used as the column name.
Annotations based Inheritance mapping in Hibernate:
There are three kinds os inheritance mappings in hibernate.
They are
1.Table per Class hierarchy:
#Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.
#DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied
If the #DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to "DTYPE" and the discriminator type to DiscriminatorType.STRING.
#DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.
2.Table per sub Class hierarchy:
#InheritanceType – Defines inheritance strategy options. JOINED is a strategy in which fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass.
#PrimaryKeyJoinColumn – This annotation specifies a primary key column that is used as a foreign key to join to another table.
3.Table per Concrete class hierarchy:
#InheritanceType – Defines inheritance strategy options. TABLE_PER_CLASS is a strategy to map table per concrete class.
#AttributeOverrides – This annotation is used to override mappings of multiple properties or fields.
#AttributeOverride – The AttributeOverride annotation is used to override the mapping of a Basic (whether explicit or default) property or field or Id property or field.
Hope it help's to get idea on basic annotation used in hibenate.

Categories