Mapping hibernate entity Many to one - java

I’m a little lost in my hibernate mapping.
I have these entity :
CommandLine :
idCommand
idCommandeLine
idItem
idStore
dateCommand
Item :
idItem
libItem
price
Store :
idStore
idWarehouse
libStore
Warehouse :
idWarehouse
libWarehouse
Stock :
idItem
idWarehouse
qtyStock
I want to add a qtyStock attribute in CommandLine.
The goal is, when I loop thought commandLines object, I can get the qtyStock of the item.
Based on the idStore, we can get the idWarehouse, and get the qty.
But how translate this in my hibernate XML Mapping ?

Don't use HBM XML mappings. The annotation mapping model is the preferred choice and you will find plenty of tutorials and help here for that model. If you really must use HBM XML mappings, we need more details. What did you try so far and did not work? How do your current mappings look like?

Related

How to dynamically add Entity in Hibernate?

I'm a java developer. I'm using spring 4.0.1 and hibernate 4.2.21. I have a class as follow:
#Entity
#Inheritance(...)
public abstract class Feature{
#Id
#GeneratedValue
protected Long id;
...
}
Now I have some many class as follow:
Label.java class:
#Entity
public class Label extends Feature{
protected String str;
...
}
Point.java class:
#Entity
public class Point extends Feature{
protected Integer intg;
...
}
I have more than 20 Entity class that extends from Feature class. Is there any way to add dynamically this classes(such as Label and Point) to the project without writing hard code?
update:
For example, Hibernate get data from a database and then according this data, create models.
Is it possible?
How do I do?
I think its not a good database design that needs to be changed dynamically. It sounds verbose and not consistent. Observe your domain again and try to design a proper entity relationships that wouldnt be changed over run time.
You can try to collect the needed data to build the model and generate a hibernate hbm.xml file for each entity (is xml format and easy to generate with java after reading the data needed as you describe in your update)
After that, you can create programmatically a hibernate configuration object following this http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html#configuration-programmatic
I Think with that approach you can achieve what you want if I understand well your question.
I think you want to generate your entity class at runtime instead of that you have to write your java file and compile it and so on.
If this is your requirement you can use a byte code generator like javassist to generate and annotate your class file at runtime. Then you can persist it to your table using JPA, Hibernate and any other ORM framework.
As I understand you need to develop a tool, collects table names that have one-to-one relationship with Feature table.
My suggestion is like that (tested with Oracle):
1) From your DB, get tables metadata who is referancing your Feature table.
Below will print your Label, Point, etc tables who has foreign key relation to your table.If you want to only generate a subset (irrelevant tables might has this relationship too) may be you put a common foreign key column name and filter out non-related tables with a help of such marking.
Connection connection = jdbcTemplate.getDataSource().getConnection();
DatabaseMetaData metaData = connection.getMetaData();
ResultSet exportedKeys = metaData.getExportedKeys(connection.getCatalog(), "<your_schema_name>", "FEATURE");
while (exportedKeys.next()){
String fkTableName = exportedKeys.getString("FKTABLE_NAME");
String fkColumnName = exportedKeys.getString("FKCOLUMN_NAME");
System.out.println("[fkTableName:" + fkTableName + "], [fkColumnName" + fkColumnName + "]");
}
exportedKeys.close();
2) For the tables you collected above, for each table of our concern, get table metadata for the types and columns.
ResultSet columns = metaData.getColumns(connection.getCatalog(), "<your_schema_name>", "<your_table_name>", null);
while (columns.next()){
String columnName = columns.getString("COLUMN_NAME");
String typeName = columns.getString("TYPE_NAME");
System.out.println("[columnName:" + columnName + "], [typeName" + typeName + "]");
}
columns.close();
3) According to result from 2 generate your Java classes. With fields, getter setters, annotations etc. Then copy them into your source directory. You know the rest :)
Hope this is helpful.
I think you can use Hibernate Reverse Engineering to generate Entity for all the database tables. Please refer this Link. That will explained step by step process to generate entity from database using hibernate reverse engineering.
Do not repeat yourself.
If you really need those classes use an IDE (like eclipse) to generate the classes. Or use generics and inheritance to create only one class that is capable of storing Strings as well as Integers.
But if you do not actually need classes, generate SQL (not JPQL nor HQL) and to store the data in java.util.Map and similar data structures.
Classes are good for:
type safety
combining logic (methods) with data (fields)
describing relationships
In your case you might only need:
store structured data at runtime.
I think you could do this with eclipse, but the classes had to be modified more or less to preserve the inheritance hierarchy.
Righ click on the project name and select Properties
Use project facets if project facets not enabled
Click the JPA if it's not selected, then click OK to close the project properties window.
After enabling JPA in project properties, now right click you eclipse project name again, you should see a new context menu item JPA tools appears. Choose Generate Entities from tables
Select a database connection to let Eclipse get the tables used to generated
class from.
Here is how to setup db in eclipse
It's better to create the entities in a dummy project using the above method and copy the Entity classes to the real project.
Eclipse's Class refactoring may be used to preserve the inheritance hierarchy that you want.
Hope this helps.

setting an embedded id in a class in hibernate , using XML files

I would like to know how can we set a embedded primary key without annotations , it means with the mapping shadow files of hibernate ?
For Hibernate verion 4.1: In the documentation you find an example for what you want. Both XML and annotation is put there next to each other.
5.1.2.1.3. Multiple id properties with with a dedicated identifier type: #IdClass and corresponding XML mapping
5.1.2.1.1. id as a property using a component type: #EmbeddedId and corresponding XML mapping

how to get query result as XML in hibernate?

I am using struts2 with hibernate. Does anyone know if it is possible to return query result as XML instead of ArrayList of domain objects?
Hibernate by default maps and persists a database record thought POJO , but in fact it also supports persisting , mapping and representing a database record in XML by using an experimental features called Dynamic models.
For example , to output a record in XML:
/**Get the a new session that is in the DOM4J EntityMode**/
Session dom4jSession = session.getSession(EntityMode.DOM4J);
Element outputXML=(Element) dom4jSession.get(Employee.class, employeeId);
XMLWriter writer = new XMLWriter( System.out, OutputFormat.createPrettyPrint() );
writer.write( outputXML);
To configure the format of the outputted XML , you can only do it by mapping the entity in XML . AFAIK ,there are no annotation equivalent .
Hibernate is an Object-Relational Mapper, meaning it maps a Relational database to objects. You want to use Hibernate to return an object and then use an XML Serializer to convert to XML.
The Simple Serializer is probably the best one to get started with. The Website contains a lot of tutorials and examples.
http://simple.sourceforge.net/
However there are a ton of XML Serializers for Java:
http://karussell.wordpress.com/2009/09/03/xml-serializers-for-java/
Maybe you could, once you have the result use XStream to parse the entire result to XML. A simple tutorial on XStream is available here.

Mapping Map<Interface,Interface> with Hibernate

Hey people, i have a the following map* which is giving me lots of trouble:
Map<MetricSourceInterface, AliasesInterface>
MetricSourceInterface is an entity with simple properties.
AliasesInterface is an entity with only an Id and a list of strings.
Hibernate is creating the database schema so theres no problem with changing it whatsoever.
On a side-note, this is a sub problem from trying to map:
Map<MetricSourceInterface, List<String>>
Does anyone know the proper way to solve this?
Theres only one limitation for this, i dont want to create an UserType for AliasesInterface or List
Thx in advance :)
*edited with pstanton's correction :)
As long as AliasesInterface is indeed an entity in Hibernate sense, there's really no problem with mapping this:
#OneToMany(targetEntity=AliasInterface.class)
#MapKeyManyToMany(targetEntity=MetricSourceInterface.class, joinColumns=#JoinColumn(name="metric_source_id"))
private Map<MetricSourceInterface, AliasesInterface> myMap;
Note that the above assumes that both AliasInterface and MetricSourceInterface are entities; if they are indeed interfaces you'll need to refer to their concrete implementations instead.
Keep in mind that #MapKeyManyToMany is Hibernate extesion to JPA. More details / examples on mapping collections are in Hibernate docs.
Update: The same approach using XML mapping files:
<map name="myMap">
<key column="owner_id"/> <!-- FK to owner entity table -->
<map-key-many-to-many column="metric_source_id" class="MetricSourceInterface"/>
<one-to-many class="AliasesInterface"/>
</map>
There are more details here and other examples here.

Running hibernate tool annotation generation without the "catalog" attribute

when i run my hibernate tools
it reads from the db and create java classes for each tables,
and a java class for composite primary keys.
that's great.
the problem is this line
#Table(name="tst_feature"
,catalog="tstdb"
)
while the table name is required, the "catalog" attribute is not required.
sometimes i want to use "tstdb", sometimes i want to use "tstdev"
i thought which db was chosen depends on the jdbc connection url
but when i change the jdbc url to point to "tstdev", it is still using "tstdb"
so,
i know what must be done,
just don't know how its is done
my options are
suppress the generation of the "catalog" attribute
currently i'm doing this manually (not very productive)
or i could write a program that parses the java file and remove the attribute manually
but i'm hoping i don't have to
OR
find a way to tell hibernate to ignore the "catalog" attribute and use the schema that is explicitly specified.
i don't know the exact setting i have to change to achive this, or even if the option is available.
You need to follow 3 steps -
1) In the hibernate.cfg.xml, add this property
hibernate.default_catalog = MyDatabaseName
(as specified in above post)
2) In the hibernate.reveng.xml, add all the table filters like this
table-filter match-name="MyTableName"
(just this, no catalog name here)
3) Regenerate hibernate code
You will not see any catalog name in any of the *.hbm.xml files.
I have used Eclipse Galileo and Hibernate-3.2.4.GA.
There is a customization to the generation, that will tell what tables to put in what catalog.
You can specify the catalogue manually (in reveng file, <table> element), or programmatically (in your custom ReverseEngineeringStrategy class if I remember well).
Also, I recently had to modify the generation templates.
See the reference documentation :
http://docs.jboss.org/tools/archive/3.0.1.GA/en/hibernatetools/html_single/index.html#hibernaterevengxmlfile
you can customize the catalogue of each of your tables manually
https://www.hibernate.org/hib_docs/tools/viewlets/custom_reverse_engineering.htm watch a movie that explains a lot ...
http://docs.jboss.org/tools/archive/3.0.1.GA/en/hibernatetools/html_single/index.html#d0e5363 for customizing the templates (I start with the directory that's closest to my needs, copy all of them in my own directory, then edit as will)
Sorry, this could get more precise, but I don't have access to my work computer right now.
The attribute catalog is a "connection" attribute and should be specified in the "connection" config file hibernate.cfg.xml and NOT in a "data" config file *.hbm.xml.
I generate hibernate code via ant task <hibernatetool> and I put this replace task after regeneration (replace schema-name with your database).
<replace dir='../src' token='catalog="schema-name"' value=''>
So, after generation, attribute catalog has been removed.
This is a workaround, but code generated works in my development a production environment with different schema-name.

Categories

Resources