i've got 2 tables:
Seat(roomID,seatID,...)
SeatState(roomID,seatID,date,state)
i wanna create a seat class and i would like this class to have a Map attribute. does somebody know how to map this thing?
Hibernate supports using 'Map's as collections. If you are using hbm.xml files, you can use the <map> tag for this purpose. Take a look at http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html for a reference. Also Hibernate supports mapping Calendar fields to TIMESTAMP fields.
So if you are using XML, it should be something like
<map name="booking" table="BOOKING">
<key column="BOOKING_ID"/>
<map-key column="BOOKING_DATE" type="calendar"/>
<element column="IS_BOOKED" type="boolean"/>
</map>
Likewise, JPA / Hibernate Annotation alternatives also exist. You need to use #Embeddable to get this done. See http://hwellmann.blogspot.com/2010/07/jpa-20-mapping-map.html for an example.
Related
Since SessionFactory#getClassMetadata(java.lang.Class) was deprecated, I am not able to use ClassMetadata. I would like to access to the following methods:
org.hibernate.metadata.ClassMetadata#getNaturalIdentifierProperties
org.hibernate.metadata.ClassMetadata#hasNaturalIdentifier
According to the documentation, I should replace getClassMetada with EntityManagerFactory.getMetamodel(). However, the metamodel does not contain methods to get natural-id. I am using xml mapping for natural-id and I would like to get the property names of the natural-id to create a dynamic query.
<class name="User">
<cache usage="read-write"/>
<id name="id">
<generator class="increment"/>
</id>
<natural-id>
<property name="name"/>
<property name="org"/>
</natural-id>
<property name="password"/>
</class>
Is there a way to use those methods to get the natural id mapping?
Is there another way to get a ClassMetadata instance?
Is it possible to get an instance of entityMetamodel to replace the ClassMetadata?
Well, knowing that SessionFactory#getClassMetadata(java.lang.Class) was deprecated, the option is using sessionFactory.getMetamodel(). Checking into hibernate code, this was my solution:
MetamodelImplementor metamodel = (MetamodelImplementor) sessionFactory.getMetamodel();
ClassMetadata classMetadata = (ClassMetadata) metamodel.entityPersister(entityName);
First, one part important to know is what entityName is. It could be the name of the mapped entity or Entity.class.getName(). Knowing that, to replace SessionFactory#getClassMetadata(java.lang.Class) with should get the name of the class and pass it as an string.
String entityName = EntityClass.class.getName();
Second, Hibernate has an implementation of JPA metamodel, named MetamodelImplementor.
Additionally, metamodel.entityPersister() returns an EntityPersister interface. Hibernate implements it using AbstractEntityPersister. And that is an abstract class which implements Lockable and ClassMetadata interfaces.
EntityPersister (interface) --> Lockable (interface) -->
AbstractEntityPersister (abstract class)
ClassMetadata (interface) --> AbstractEntityPersister (abstract class)
So, it is possible to cast AbstractEntityPersister to ClassMetadata. And in that way return same object.
This is a portion of code of Hibernate in SessionFactoryImpl:
public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
return (ClassMetadata) getMetamodel().entityPersister( entityName );
}
I have been working in .NET using Entity Framework with fluent API.
I created database context with all the relations of entities to map with tables and relations with entities with one to many etc.
I know the annotations way and mapping via XML files.
Following is the code in c#
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.Property(u => u.DisplayName)
.HasColumnName("display_name");
}
}
Can any one tell me how to set a file in hibernate in JAVA to create the Blogs table for entity Blog and set properties for any entity with database rather then creating adding annotations.
Just some suggesions: Hibernate does not have the concept of Context but I usually insert a Context class where I set Hibernate Configuration class (one time for the project) and where I retrieve a session (Configuration.BuildSessionFactory() to get a ISessionFactory one time for the project and then ISessionFactory.OpenSession() or other methods similar to it). A session is the class where you start to build queries and insert/update/delete objects (so the usage is similar to the EF Context - you don't implement a Session like a DbContext -).
Usually you build the mapping using xml files like this
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="FiPlan.Data.Entities" assembly="FiPlan.Engine">
<class name="Account" table="Accounts" >
<id name="Id" column="ID" type="String" length="15" >
<generator class="assigned" />
</id>
<property name="Description" column="Description" type="String" not-null="false" length="50" />
</class>
</hibernate-mapping>
You add this files to the Configuration class (the one where you start to get a session).
Another consideration: there isn't the DbSet concept (every configured class can be accessed via queries).
I know that is not what you are looking for but I hope that this could be an help when you will start to read the Hibernate manual.
In short - I didnt find any way to create mapping or file like context for hibernate like in Entity Framework .NET
Is there a simple way to externalize big sql queries from jdbc outbound gateways, instead of inlining it? The reason being that we're having to many big queries to make, and we'd like to have them on their own files, or at least externalize them in beans.
Some caveats:
I don't have control over the database, so I can't create anything
there (e.g. stored procedures)
I don't want to create classes just for this matter, I just want to organize/refactor it a bit, and not make it more complex
introducing many other steps
I'd prefer to create bare .sql files, but putting the queries in an xml withing a bean is okay too
I don't have the option of using hibernate, stuck to spring integration jdbc
Suggestions on how to better organize this, considering that we're going to have many others outbound gateways are welcome :)
For instance, I wouldn't like to have the SQL inline in the "int-jdbc:outbound-gateway" element as follows:
<int-jdbc:outbound-gateway
data-source="datasource"
request-channel="reqChannel"
reply-channel="respChannel"
row-mapper="datamapper" max-rows-per-poll="1000"
query=" SELECT Field1, Field2, ManyOthers
FROM Table T
JOIN A ON A.id = T.id [... many other joins here ...]
WHERE SOMECONDITION=:payload">
</int-jdbc:outbound-gateway>
What I've done using the answers
Simply:
<bean id="myCoolQuery" class="java.lang.String">
<constructor-arg>
<value>
<![CDATA[
SELECT Field1, Field2, ManyOthers
FROM Table T
JOIN A ON A.id = T.id [... many other joins here ...]
WHERE SOMECONDITION=:payload
]]>
</value>
</constructor-arg>
</bean>
<int-jdbc:outbound-gateway
data-source="datasource"
request-channel="reqChannel"
reply-channel="respChannel"
row-mapper="datamapper" max-rows-per-poll="1000"
query="#{myCoolQuery}">
</int-jdbc:outbound-gateway>
It also works with the ":payload" parameter used inside the bean.
Yes, you can put them in a properties file, and use properties placeholders ${...} to resolve them, or you can use SpEL...
"#{myQueryBean.queryOne}"
where myQueryBean is a <bean/> that's an instance of a class with a method...
public String getQueryOne() {...}
or a static constant on a class...
"#{T(foo.Queries).QUERY_ONE}"
public static final String QUERY_ONE = "...";
You can define your queries in XML as spring beans:
<bean id="exampleQuerySql" class="java.lang.String">
<constructor-arg>
<value>
<![CDATA[
select * from foo
where whatever_ind = 'A'
]]>
</value>
</constructor-arg>
</bean>
Using CDATA the query text can include newlines, angle brackets, etc., so it's legible and you can cut and paste it directly into a SQL tool.
You can refer to the bean using SpEL.
Asking this question here after hours of frustration with me and my Eclipse. Hoping to find some respite here.
I'm trying to save a pojo object into MySQL database via Hibernate 3.0. Basically my requirement is: I need to assign the id for the object before save and not let Hibernate do it for me.
For this I looked up in the documentation and saw that <generator class="assigned"/> perfectly fits my bill. Consequently I updated by .hbm.xml file with the following for the id:
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
My pojo matches .hbm.xml file to the T.
I'm setting all the parameters including the ID of my pojo and calling Hibernate's saveOrUpdate(object) method.
If it's of any help, the ID column of my database table has "auto-inc" disabled.
Unbelievably, when I look at the database table contents, a row has been inserted with Hibernate's own ID and not what I had set.
How's it possible? Is there anything else affecting the ID? Am I missing on something? What's the work around?
My hibernate.properties looks like below(if it's of any help):
hibernate.connection.driver_class =com.mysql.jdbc.Driver
hibernate.dialect =org.hibernate.dialect.MySQLDialect
hibernate.connection.url =jdbc:mysql://localhost/dbdbdbdbdb
hibernate.connection.username=root
hibernate.connection.password=password
hibernate.connection.pool_size=10
jdbc.batch_size=30
hibernate.show_sql=true
hibernate.current_session_context_class=true
hibernate.hbm2ddl.auto=validate
hibernate.cglib.use_reflection_optimizer=false
hibernate.generate_statistics=true
hibernate.cache.use_query_cache=true
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory
Well, hoax alarm!. It was really an issue with Eclipse-Tomcat integration. I had to clean up Tomcat's directories and republish before the hbm files could take effect.
Tip: If you run ant within Eclipse, be sure to keep refreshing Eclipse workspace every now and then. Learning some things the hard way.
You can write your custom sequence generator class to return ids suitable to your requirement. For more details follow: http://danu-javastuff.blogspot.com/2009/01/custom-id-generator-class-for-hibernate.html
I want to add a (where) condition in hibernate mapping file when fetching,
how could i do that for example fetch="select" where id != 1 ,am not using annotations also, so please specify within the mapping (hbm) files.
According to the Hibernate documentation, you can specify a where clause when mapping a collection:
6.2. Collection mappings
(...) The <map> element is
representative:
<map
name="propertyName" (1)
table="table_name" (2)
schema="schema_name" (3)
lazy="true|extra|false" (4)
inverse="true|false" (5)
cascade="all|none|save-update|delete|all-delete-orphan|delet(6)e-orphan"
sort="unsorted|natural|comparatorClass" (7)
order-by="column_name asc|desc" (8)
where="arbitrary sql where condition" (9)
fetch="join|select|subselect" (10)
batch-size="N" (11)
access="field|property|ClassName" (12)
optimistic-lock="true|false" (13)
mutable="true|false" (14)
node="element-name|."
embed-xml="true|false"
>
<key .... />
<map-key .... />
<element .... />
</map>
(...)
(9) where (optional): specifies an
arbitrary SQL WHERE condition that is
used when retrieving or removing the
collection. This is useful if the
collection needs to contain only a
subset of the available data.
This is also supported at the <class> level.
You could perhaps define a <filter> in the mapping file, and attach it to the class mapping definition. See the docs for examples.