Hibernate - reusable component definition in XML? - java

Is it possible to have reusable component definition in XML like pair #Embeddable and #Embedded ?
I've a complex component mapping and have to use it 10+ times throw XML mapping (yes, I know hot to copy mapping, but hope for a better solution). Unfortunately can't use annotations ...

Please be more specific as to what you trying to do?
If you are asking if the attributes of a component can be mapped to different columns then as per the documentation - and verified by you - you can do this:
#Embedded
#AttributeOverrides( {
#AttributeOverride(name="iso2", column = #Column(name="bornIso2") ),
#AttributeOverride(name="name", column = #Column(name="bornCountryName") )
} )
Country bornIn;
This will map the iso2 field in Country class to bornIso2 and name to bornCountryName. Hope this helps

Related

Hibernate override "lazy=false"

I am working on a new module in an existing project. The project already has a user table, a pojo and a corresponding mapping file. The problem is that they are fetching all the properties eagerly by mentioning lazy="false". But, in my module, I am doing lot of read & write in a single request, so I don't want to fetch eagerly. What I want to know is that, is it possible to create an another mapping file for the same table & same pojo to load all the properties lazily? I have tried by assigning different entity-name for the mapping files, but while deploying, I am getting the error "Repeated column in mapping for entity".
I saw this answer, but it says "do not map child", then how will I get the proxies?
That's one major drawback for using EAGER fetching as the default strategy. Usually you'd have a LAZY children collection that you can eagerly fetch on a HQL query basis.
What's worth mentioning is that HQL/Criteria queries overrule the default fetch strategy (the one given by your entity mappings) so that you can explicitly specify what to fetch.
For Criteria queries, you might give a try to Criteria.setFetchMode FetchMode.LAZY, although it's deprecated.
Another way to overrule the EAGER fetching is to use a javax.persistence.fetchgraph. This way, you can specify what you want to fetch and all the EAGER fetching properties that were not included in the Entity Graph are going to be fetched lazily.
I think, your question is to not to load associated entity , egarly ?
for this when :
FetchType.LAZY = Doesn’t load the relationships unless explicitly called via getter.
FetchType.EAGER = Loads ALL relationships default
In your case , if my understanding is correct then use
lazy="false"
fetch="select" so it will select on demand via getter.
check this url , it will give more clear idea :
Hibernate XML Mapping: Lazy False or Fetch Select?
A Short Primer On Fetching Strategies
The point Hibernate mapping setting lazy = 'false' is making, is that you can map the same table twice if you use two different java classes. In your case, if you know for a fact that setting lazy="true" will suffice:
create empty subclass of your pojo
map your subclass the way you want to the same user table (for examply copy-pasting the existing mapping and changing lazy property value)
in the module you create only use the subclass
Like Vlad Mihalcea said, use Criteria API it will work. I've tried it :)
Criteria c = session.createCriteria(YourHibernateClass.class);
c.setFetchMode(urLazyPropName,FetchMode.LAZY);
Atleast this you can do with out changing existing hbm files
Some other approaches mentioned we used based on JPA inheritance (#MappedSuperclass) and/or database views and examplified with the following pseudo code (it works both ways for EAGER->LAZY or LAZY->EAGER scenarios):
#Table( name = "table_x" )
#Entity
class DaoX { #...( fetch = FetchType.EAGER ) refY ; /* ... other stuff ... */ }
our DaoX used e.g. in other code like this:
DaoX x ;
#Entity
class DaoZ { DaoX x ; }
via inheritance
so if we would like to have it lazily loaded we could pimp the inheritance hierarchy up like this with only minimal additional code:
#Table( name = "table_x" )
#MappedSuperclass
class abstract BaseDaoX { /* ... other stuff ... */ }
#Entity
class DaoX extends BaseDaoX { #...( fetch = FetchType.EAGER ) refY ; }
#Entity
class DaoXLazy extends BaseDaoX { #...( fetch = FetchType.LAZY ) refY ; }
our DaoX usages should be substituted by BaseDaoX where possible (no direct JPA mapping)
BaseDaoX x ;
#Entity
class DaoZ { DaoX x ; }
#Entity
class DaoZLazy { DaoXLazy x ; }
so you can use DaoXLazy or DaoZLazy for your desired scenarios.
via views (in LAZY->EAGER scenarios)
(if you can change your current EAGER to LAZY which is generally more appropriate)
you could just map your (maybe deeply nested) lazy stuff with minimal load e.g. like this ( we like to load prop_f1 and prop_b1 here )
-- db view:
create or replace view view_x_eager as
select
tx.*,
f.prop_f1,
b.prop_b1
from table_x tx
-- assuming tx:f ~ 1:1 and f:b ~ 1:1 for simplicity here:
left outer join table_foo f on ( f.id = tx.foo_id )
left outer join table_bar b on ( b.id = f.bar_id )
#Table( name = "view_x_eager" )
class DaoXEager extends BaseDaoX {
#...( fetch = FetchType.EAGER ) refY ;
String prop_f1 ;
String prop_b1 ;
}

Hibernate many to many mapping additional column Timestamp

I am a newbie to Hibernate and trying to do something like this:
I have 2 tables.
One is Visitor and another is Visited_Page.
The Visitor table has a structure:
{
visitor_id *int*,
visitor_username *varchar*,
visito_name *varchar*
}
The Visited_Page table structure is:
{
vipage_id *int*,
vipage_url *varchar*
}
And many to many mapped table structure is like:
visitor_id int, vipage_id int.
When the User hits a URL in my website, a new entry should get created in the mapped table with the structure as mentioned above.
I have completed this part using hibernate with annotations in Java.
Now I have to add another column Timestamp in the mapped table. I am not able to find how to do it. Please help.
Create a class say VistorVisitedPage
#Entity
#Table(name = "Vistor_Visited_Page")
#AssociationOverrides({
public class VistorVisitedPage {
private Date createdDate;
private String createdBy;
}
Also refer this for complete information.

How to handle internationalization of names in Hiberante and db schema

I saw a few questions in stackoverflow, but they all refer to old answers (from 2004) and using hibernate xml mappings.
I am writing an API in Java, which will return products which are stored in the database based on an algorithm.
The API would also get a locale and decide to return the name in the locale language.
Product table:
product_id
name
price
How should I support internalization?
Should I add name_en name_fr etc columns?
Or should I create different tables?
How should I return the name in the required locale in Hibernate?
I am using annotations for O/R mapping
I would suggest adding a column "lang" that contains prefix of language (ex. en, fr, ro, etc.) and a column "name" that contains the name in all languages separated by a separator like "," and parse the string.
I would remove the name column, and create a one-to-many relationship with a separate table named localized_name:
create table localized_name (
product_key int not null,
locale nvarchar(32) not null,
name nvarchar(255) not null
)
My experience is with JPA, not Hibernate, but I'm guessing the code looks similar in both:
public class Product {
private Collection<LocalizedName> names;
}
In JPA I would add a #Size(min = 1) annotation to the field to ensure it contains at least one element when it is persisted.

How to convert between GRAILS' class column and hibernate's DTYPE column in GORM

I have the following problem. I got a database schema generated by JPA/Hibernate in Java. I have one table for an inheritance hierarchy. For this to work Hibernate uses a DTYPE column to distinguish between the concrete implementations of the classes in my hierarchy.
I now need to load that same hierarchy to GRAILS domain objects. However GRAILS uses a column with the name 'class' to save the names of the concrete implementation and I was not able to find any way to change this mapping. So my question is: is there a way to map GRAILS' 'class' column to Hibernate's DTYPE column?
You can customise the name used for the discriminator column in the base class mapping closure.
class TopOfTheHierarchy {
…
static mapping = {
discriminator column: "DTYPE"
}
}
To use something other than the class name as the discriminator value you use a similar mapping entry for each subclass
class ChildClass {
…
static mapping = {
discriminator "child"
}
}
If you already have a DB schema you can try using Grails Database Reverse Engineering Plugin to generate your Grails domain class from your schema.

Tag system to replace categories in Spring - Hibernate java project

Does anyone know how to go about designing tag system similar to the one used here, at stackoverflow?
Any links that would explain on how to go about implementing this system with hibernate/spring would be awesome.
I'm just looking for some starting point.
aroth's answer of three entities is perfectly valid, but we do the same thing using just two entities because the third one (ie TaggedPost) doesn't add any value for us.
Our entities look something like this:
#Entity
#Table(name = "Tag")
public class Tag {
#ManyToMany(fetch=FetchType.LAZY)
#JoinTable(
name="PostTag",
joinColumns=#JoinColumn(name="TagId"),
inverseJoinColumns=#JoinColumn(name="PostId")
)
#ForeignKey(name="FK_Tag_Post", inverseName="FK_Post_Tag")
private Set<Post> posts;
/* ... */
}
#Entity
#Table(name = "Post")
public class Post {
#ManyToMany
#JoinTable(
name="PostTag",
joinColumns=#JoinColumn(name="PostId"),
inverseJoinColumns=#JoinColumn(name="TagId")
)
#ForeignKey(name="FK_Post_Tag", inverseName="FK_Tag_Post")
#Sort(comparator=CompareTagByName.class, type=SortType.COMPARATOR)
private SortedSet<Tag> tags;
/* ... */
}
The advantage is that we don't need to manually maintain the join. We simply add or remove a Tag from each Post as needed.
Note also:
lazy fetching on Tag.posts is a good idea... otherwise you might cause Hibernate to unnecessarily load thousands of Post records each time a tag is displayed.
the many-to-many join makes it easy to sort the tags in alphabetical order, by providing a Comparator with a #Sort annotation
I would suggest starting with three Entities, one for the object that is being tagged (is in the case of the SO example, this would be a Post), one for holding your tag definitions (you can just call this Tag), and one for mapping between the two (call this one TaggedPost).
Then the basic process of assigning a Tag to a Post goes something like:
See if a Tag with the given name already exists, if yes, use the existing one, otherwise insert a new one.
Create a new TaggedPost instance that links the Post with the Tag from step 1.
To remove a Tag from a Post you just delete the corresponding TaggedPost entity.
You can use Hibernate annotations to expose the set of tags that are applied to a given Post as a Java Collection so that you can just say getTags() to get all the tags. And you can do the same thing on Tag so that you can say getPosts() to get all the posts that have a given Tag.

Categories