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.
Related
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?
I've seen this question asked a lot and I know why it happens, I'm just having issues trying to solve it in my specific case.
I'm converting the project I'm working on from using XML files to map classes to database tables for Hibernate, to using Hibernate annotations. Everything is going fine as long as I'm using basic java types (primitives or class versions of primitives, e.g. int or Integer). But when it comes to my class having a member that is another class of mine, things go south.
One type of issue is when I have OnetoMany relationship.
In the XML file for foo it says this:
<set inverse="true" name="barList">
<key>
<column name="foo_id"/>
</key>
<one-to-many class="com.me.model.dao.Bar" />
</set>
In converting this to an annotation, I end up with this:
#OneToMany
#JoinTable(name = "bar", inverseJoinColumns = #JoinColumn(name = "foo_id"))
public Set<Bar> getBarList() {
return barList;
}
I've tried other variations of this (including have a JoinColumn), and I know as it stands it may be incomplete, but like I said, I'm having trouble finding a proper solution to get rid of the lazy initial exception when I'm working with the objects in the view of my MVC. FetchType.EAGER is said to be a workaround and not a solution, but curiously, solutions are not offered. Maybe more information is needed.
My MVC is Wicket 1.4.17.
My app server is Widlfly (i.e. no web.xml)
Java version is 8.
Hibernate, through Maven POM
artifact : hibernate
version : 3.5.0.ga
artifact : ejb3-persistence
version : 1.0.1.GA
Edit: It might be helpful to add that while barList appears in the foo class, there is no reference of any kind to bar in foo in the database. The foo table does have a bar_id.
Actually, annotation help to make the mapping more simple and easily. Both xml or annotation are also the same ideas(to make Hibernate to understand our objects' relationship). In this case, the mapping just simple like:
#OneToMany(mappedBy="foo")
private Set<Bar> barList;
For the whole detail, this sample looks like the same yours: https://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/
Hope this help.
I think it depends on your transaction management configuration because when you use FetchType.LAZY your lazy list not loaded until you call it by its getter method.
So that if you invoke getter method after commit transaction, this exception throws.
Please check your transaction configuration or send that part of code here.
I have a legacy application that uses hibernate for mapping objects into a database. It uses the Hibernate Mapping XML file to do so. The java class contains two properties abc and def that implement java Serializable. The mapping is defined this way:
<property name="abc" column="ABC" type="serializable" length="32672"/>
<property name="def" column="DEF" type="serializable" length="32672"/>
When I try to set this up with oracle, I get a nasty error "ORA-01754: a table may contain only one column of type LONG" which essentially is complaining about creating two 'long raw' columns in one table. Oracle does not like this. After reading up on the issue, the recommended approach is to use blobs instead of 'long raw' types.
My question is, how can I express in the hibernate mapping file to use a serializable type mapped into a blob column? I would think there would be a serializable_blob type but there does not seem to be.
I know this is possible with JPA annotations using #Basic and #Lob. It should also be possible using the hibernate mapping file. How can this be done in the hibernate mapping file?
Update:
The following do not work as Serializable works:
type=binary - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
type=blob - - This one expects a java.sql.Blob. Does not work for Serializable classes. Gives ClassCastException.
type=materialized_blob - - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
<property
name="data"
type="blob"
column="DATA"/>
...
should work.
Ok, did some more research following my comment above and, by Jove, I found it.
In Hibernate 3.5 + Spring 3.1, I used Spring's org.springframework.orm.hibernate3.support.BlobSerializableType. Now I'm upgrading to Hibernate 4.3, that option isn't available anymore. I did find the type to column mappings as OP, but in my application there are various Strings (legacy) that are mapped to BLOB fields.
So, as I reported in the comment above, I found the org.hibernate.type.SerializableToBlob type, which is parameterize. Below how I got the mapping to work (using good old-fashioned hbm.xml mappings)
<property name="description" column="TEXT">
<type name="org.hibernate.type.SerializableToBlobType">
<param name="classname">java.lang.String</param>
</type>
</property>
And that appears to do the trick. (the classname value should be the type of the attribute you are mapping, I think)
I have a hibernate mapping:
<properties name="lrt_bps_bpr_acs_uk" unique="true">
<many-to-one name="activitySummary" column="bps_acs_id" class="xyz.ActivitySummary"
unique-key="lrt_bps_bpr_acs_uk"/>
<many-to-one name="bestPractice" column="bps_bpr_id" class="xyz.BestPractice"
unique-key="lrt_bps_bpr_acs_uk"/>
</properties>
I expected that hibernate would create unique constraint on database for this mapping. Nothing like that happened however.
What am I doing wrong?
Seems like you do nothing wrong. We do it the same way in our project and it works fine.
I thought to have the same problem once because I couldn't find the constaints in our oracle DB because I thought the specified unique-key attribute value (in your case 'lrt_bps_bpr_acs_uk') is used as constraint_name in the DB. But that isn't the case (at least with oracle DB).
What's the actual DDL that Hibernate is generating? What would be the DDL if you remove the unique-key parameters? What's the Hibernate version?
From the documentation, it seems you are doing it correctly:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-properties
Dont specify name="lrt_bps_bpr_acs_uk" unique="true" in the properties element. It automatically takes it and applies the constraint with unique-key
I am trying to use dozer 4.1 to map between classes. I have a source class that looks like this:
public class initRequest{
protected String id;
protected String[] details
}
I have a destination class that looks like this:
public class initResponse{
protected String id;
protected DetailsObject detObj;
}
public class DetailsObject{
protected List<String> details;
}
So essentially i want the string in the details array to be populated into the List in the Details object.
I have tried a mapping like this:
<mapping wildcard="true" >
<class-a>initRequest</class-a>
<class-b>initResponse</class-b>
<field>
<a is-accessible="true">details</a>
<b is-accessible="true">detObj.details</b>
</field>
</mapping>
But I get this error:
Exception in thread "main" net.sf.dozer.util.mapping.MappingException: java.lang.NoSuchFieldException: detObj.details
at net.sf.dozer.util.mapping.util.MappingUtils.throwMappingException(MappingUtils.java:91)
at net.sf.dozer.util.mapping.propertydescriptor.FieldPropertyDescriptor.<init>(FieldPropertyDescriptor.java:43)
at net.sf.dozer.util.mapping.propertydescriptor.PropertyDescriptorFactory.getPropertyDescriptor(PropertyDescriptorFactory.java:53)
at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestPropertyDescriptor(FieldMap.java:370)
at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestFieldType(FieldMap.java:103)
at net.sf.dozer.util.mapping.util.MappingsParser.processMappings(MappingsParser.java:95)
at net.sf.dozer.util.mapping.util.CustomMappingsLoader.load(CustomMappingsLoader.java:77)
at net.sf.dozer.util.mapping.DozerBeanMapper.loadCustomMappings(DozerBeanMapper.java:149)
at net.sf.dozer.util.mapping.DozerBeanMapper.getMappingProcessor(DozerBeanMapper.java:132)
at net.sf.dozer.util.mapping.DozerBeanMapper.map(DozerBeanMapper.java:94)
How can i map this so that it works?
This works for me. I am using 5.2.1 version
<mapping wildcard="true" >
<class-a>initRequest</class-a>
<class-b>initResponse</class-b>
<field>
<a>details</a>
<b is-accessible="true">detObj.details</b>
</field>
</mapping>
Note that "is-accessable" is not required for . Hope it helps
Problem solved...
is-accesible allows an object to be updated regardless of access modifier and presence of getters/setters (essential for objects generated using JAXB)
"dot" notation for deep mapping works to access nested objects
Combining the two is a feature that does not work in Dozer (maybe it does in a newer version)
solution...
modify the xsd such that the deep mapping is not required. This is not my ideal solution but its better than writing a custom converter for every object
In case of JaxB, use can download and use the plugin for generating the setters. Refer to this link for more details, https://jaxb2-commons.dev.java.net/collection-setter-injector/
I would guess that accessors (getter / setter) are missing.
By the way I think that you'll also need to provide an empty constructor for DetailsObject so dozer can instanciate it.
<b is-accessible="true">detObj.details</b>
Should be replaced with
<b is-accessible="true">DetailsObject.details</b>
While it does seem you cannnot use the "is-accessible" and dot notation together another approach is to break your deep mapping into smaller mappings.
We ran into this situation with JAX-WS generated code. You have lists that have no setter methods and in our case were deeply nested. We found our solution by simply breaking the large deep mapping into smaller mappings that "walked" our way to what we wanted. I tried to explain this in my blog here:
http://btarlton.blogspot.com/2014/08/dozer-deep-nestinga-different-approach.html
But the trick is just walking the object tree by smaller mappings and using is-accessible="true" when necessary to access the list with no setter and using "this" as the property name to keep passing the source along.
Hope this helps!
To summarize there are following options for this issue
1) Use JaxB pluggin to enable setters as discussed by Naveen
2) Use is-accessible for such properties
I believe using first approach unnecessarily exposes setters for collections/lists as you can risk of setting them with null.
We decided to enable is-accessible for such fields (and not to entire class) to avoid any side effects.
I have discussed the solution at Dozer Mapping Class level is-accessible