dozermapper / dozer Goto Github PK
View Code? Open in Web Editor NEWDozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another.
Home Page: https://dozermapper.github.io/
License: Apache License 2.0
Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another.
Home Page: https://dozermapper.github.io/
License: Apache License 2.0
Probably use StackOverflow for the support, but leave some place for discussions such as Google Groups.
Hi,
First, sorry for the cross post on the Google group as well. I posted there and then realized tracking of bugs was here.
I have upgraded to the latest 5.4.0 release and found that a bug from 5.3.2 still exists. The bug in question occurs with nested mapping aware Object resolution. The relevant portion of the stack track is the following:
java.lang.NullPointerException
at org.dozer.MappedFieldsTracker.getMappedValue(MappedFieldsTracker.java:55)
at org.dozer.MappingProcessor.map(MappingProcessor.java:182)
at org.dozer.MappingProcessor.map(MappingProcessor.java:133)
at org.dozer.MappingProcessor.map(MappingProcessor.java:128)
...
Basically what happens is the following:
public void map(final Object srcObj, final Object destObj) {
map(srcObj, destObj, null);
}
calls
public void map(final Object srcObj, final Object destObj, final String mapId) {
MappingValidator.validateMappingRequest(srcObj, destObj);
map(srcObj, null, destObj, mapId);
}
where a null is passed for the destClass variable into
private <T> T map(Object srcObj, final Class<T> destClass, final T destObj, final String mapId) {
srcObj = MappingUtils.deProxy(srcObj);
Class<T> destType;
T result;
if (destClass == null) {
destType = (Class<T>) destObj.getClass();
result = destObj;
} else {
destType = destClass;
result = null;
}
...
// If this is a nested MapperAware conversion this mapping can be already processed
Object alreadyMappedValue = mappedFields.getMappedValue(srcObj, destClass);
if (alreadyMappedValue != null) {
return (T) alreadyMappedValue;
}
...
which results in destClass remaining as null and being passed into
public Object getMappedValue(Object src, Class<?> destType) {
Map<Integer,Object> alreadyMappedValues = mappedFields.get(src);
if (alreadyMappedValues != null) {
for (Object alreadyMappedValue : alreadyMappedValues.values()) {
if (alreadyMappedValue != null) {
// 1664984 - bi-directionnal mapping with sets & subclasses
if (destType.isAssignableFrom(alreadyMappedValue.getClass())) {
// Source value has already been mapped to the required destFieldType.
return alreadyMappedValue;
}
}
}
}
return null;
}
resulting in a null destType value which causes the exception.
I believe that changing
destType = (Class) destObj.getClass();
to
destClass = destType = (Class) destObj.getClass();
on line 153 of the MappingProcessor class would solve the problem but I both wanted an opinion on this and was wondering what the best means to get the fix would be.
Thanks,
Jason
i have this classes i want to map BaseInformationViewModel to BaseInformation
BaseInformationViewModel b=new BaseInformationViewModel ();
b.setMasterInformationId(1);
after map the type of BaseInformation .getMasterInformation.getId() is String
and i dont know why BaseInformation.getMasterInformation().getId ----- is String
PLZ HELM ME
public class BaseInformation extends BaseEntity{
private BaseInformation masterInformation;
public BaseInformation getMasterInformation() {
return masterInformation;
}
public void setMasterInformation(BaseInformation masterInformation) {
this.masterInformation = masterInformation;
}
}
public abstract class BaseEntityViewModel implements Serializable {
private static final long serialVersionUID = 4295229462159851306L;
private T id;
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
}
public class BaseInformationViewModel extends BaseEntityViewModel{
@Mapping("masterInformation.id")
private Integer masterInformationId;
public Integer getMasterInformationId() {
return masterInformationId;
}
public void setMasterInformationId(Integer masterInformationId) {
this.masterInformationId = masterInformationId;
}
}
I using Dozer in my project with xml mapping but i want to used annotation and remove xml file
this example show bug in annotation mapping
after mapping to destination bean ,type of variable is changed from Integer to String
for example
public class User {
private Integer id;
}
public class UserBean {
@Mapping("user.id")
private Integer userId;
}
userBean.getUserId()//is not Integer it is String
I think one of the dozer disadvantage is in annotation
annotation is very simple and changeable
Create custom XSD schema
Hello,
In dozer 5.3.2, transferring e.g. a byte[ ] located in a source object to a byte[ ] located in a destination object is using MappingProcessor.mapFromIterateMethodFieldMap .
On my machine, it takes about 1 second to transfer a byte[ ] of 1024*1024 elements.
A custom converter implemented using System.arraycopy transfers the data in less than 1ms.
Using System.arraycopy by default in such cases would be more efficient.
Identity conversion of String,Integer,... arrays (arrays of immutable types in general, especially those provided in java.lang.*) could benefit from the same optimization.
Regards
/Sebastien
if getter and setter types of src and dest classes are of wrapper and primitive, wildcard fails to consider them as mappable.
This example does not work.
Source
long get()
void set(Long)
Dest
long get()
void set(Long)
I need information about classes mapping for dinamic construct a JPA Query.
public List getFieldsMap(Class srcClass, Class destClass, String mapId)
For receiving this information I extend DozerBeanMapper and open MappingProcessor method classMappings by Reflection, but this not good idea.
If map a hibernate entity with map to pojo class with dest map field Dozer tries to create a PersistenceMap in destination class and failed with lazy initialization exception.
ERROR [MappingProcessor] - Field mapping error -->
MapId: null
Type: null
Source parent class: xxx.Model
Source field name: attributes
Source field type: class org.hibernate.collection.internal.PersistentMap
Source field value: {phone=33-33-22}
Dest parent class: xxx.ModelDTO
Dest field name: attributes
Dest field type: java.util.Map
org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:489)
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:447)
at org.hibernate.collection.internal.AbstractPersistentCollection.readElementByIndex(AbstractPersistentCollection.java:222)
at org.hibernate.collection.internal.PersistentMap.get(PersistentMap.java:165)
at org.dozer.MappingProcessor.mapMap(MappingProcessor.java:601)
Situation like this http://stackoverflow.com/questions/14213110/polymorphism-in-dozer/14237512 question couldn't be processed without custom converter now in dozer because hints are useless.
Dozer need to have some type of automatically concrete class detecting.
Hello!
I'm trying to download Dozer jars and plugins,
by: http://dozer.sourceforge.net/downloading.html
One of these links redirect-me to github page where i should find download link;
There are another way to download these jars?
Thanks!
Here is my log using mvn clean install: http://pastebin.com/e4D5xrLU
I need this new version to use the map-null in configuration. I'm getting the DOZER-5.5.0-SNAPSHOT, but when I add the in the in the dozer.xml, the map-null isn't recognised and the IDE throws an error
Hi,
Below is a description of an issue I encountered.
I created a mapping definition like this:
<field custom-converter="my.custom.Converter">
<a>mapField</a>
<b>someOtherField</b>
</field>
Field mapField contains an instance of implementation of java.util.Map.
My converter method definition looks like this:
public DestType convertTo(Map source, DestType destination)
The problem is that I get null value in source variable. I checked everything to be sure that mapField was indeed populated.
I traced the issue to MapFieldMap class. The getSrcFieldValue() method gets the source value (the Map) and then uses it's original field name (mapField) as a key to retrieve value from that map (with get("mapField")). Obviusly this is null.
I found a workaround - it is enough to specify a-hint definition. However, in my opinion, this should not be required when mapping a field with my custom converter.
I have an object which doesnt have setters and has a different get method.
so when mapping it to a different object, I have used the following mapping.
the get method returns a List of Long objects.
<mapping>
<class-a>com.service.ClassA</class-a>
<class-b>com.pojo.ClassB</class-b>
<field>
<a get-method="getLong">_long</a>
<b is-accessible="true">_long</b>
</field>
</mapping>
I get the following error
MapId: null
Type: bi-directional
Source parent class: com.service.ClassA
Source field name: _long
Source field type: class java.util.ArrayList
Source field value: [2085001]
Dest parent class:com.pojo.ClassB
Dest field name: _long
Dest field type: java.util.List
java.lang.ClassCastException: net.sf.dozer.util.mapping.propertydescriptor.FieldPropertyDescriptor cannot be cast to net.sf.dozer.util.mapping.propertydescriptor.GetterSetterPropertyDescriptor
at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestFieldWriteMethod(FieldMap.java:121)
at net.sf.dozer.util.mapping.MappingProcessor.mapFromFieldMap(MappingProcessor.java:304)
Any suggestions will be helpful.
Thanks
As a developer
I want a global map-null setting
So that I can set it to 'false' to ensure mappings-wide consistency.
In mapping processor there is a lookup made for the destType/destClass in the method:
org.dozer.MappingProcessor.map(Object, Class<T>, T, String)
The lines setup the destType if destClass was null:
Class<T> destType;
T result;
if (destClass == null) {
destType = (Class<T>) destObj.getClass();
result = destObj;
} else {
destType = destClass;
result = null;
}
Which is then incorrectly referenced later(Line 182) on resulting in a null pointer exception as destClass is null:
Object alreadyMappedValue = mappedFields.getMappedValue(srcObj, destClass);
This should be using destType instead:
Object alreadyMappedValue = mappedFields.getMappedValue(srcObj, destType);
Regards
I'm still seeing some issues in relation to generics and synthetic/bridge methods because of the documented bugs with generics and introspection...
http://bugs.sun.com/view_bug.do?bug_id=6788525
http://bugs.sun.com/view_bug.do?bug_id=6528714
I have created a bug fix to ReflectionUtils that solves these issues fully and is a very safe change (I've used this same behavior in our own app with great results). I'll shortly be sending a link to the commit
It may be useful for mapping QueryTyple resultset to WS response object without intermediate mapping to Entity object
I develop this feature in https://github.com/ikozar/dozer.git
I'm using a custom converter to convert from a String to a custom object. When I have an object that has a field that uses the custom converter, everything works fine. However, if I just have a String and I try to convert that into my custom object, my destination object never gets updated, even though my custom converter gets called. Here's a simplified example:
public class AClass {
private String customField;
//getter & setter...
}
public class BClass {
private CustomObject customField;
//getter & setter
}
I've implemented a basic custom converter, and since that gets called every time I'll omit it from here.
Now my calling code
AClass a = new AClass();
a.setCustomField("abc123");
BClass b = new BClass();
beanMapper.mapFrom(a, b);
//This updates b.getCustomField()
String str = "abc123";
CustomObject obj = new CustomObject();
//tried setting obj to null at first but this gives me the following error:
//Request processing failed; nested exception is org.dozer.MappingException: Destination object must not be null
beanMapper.mapFrom(str, obj);
//this does not update obj
Am I doing something wrong or is this an actual bug?
Hello,
Is it posible to do the mapping between one field and one class?
We need to map one field (List) of one class to an int[ ], How can I do that?
Thanks
If the destObject is a Hibernate Proxy by calling org.dozer.DozerBeanMapper.map(Object, Object) and using mapping files with wildcard="false" at a global level dozer will not map the object correctly. The bug lies in the derivation of the class in org.dozer.MappingProcessor.map(Object, Class, T, String) line 154:
destType = (Class<T>) destObj.getClass();
I will provide a test case and fix in a patch.
or add ability to create mapping - there is some problem with it by Stackoverflow.
i want to map DocumentViewModel ---->Document
after map type of Connector.id is Long but in class in integer
after write this code problem is solved
connector.id
connectorId
java.lang.Integer????????????
java.lang.Integer???????????
why i will write this line
public class DocumentViewModel extends BaseEntityViewModel {
private Integer connectorId;//
}
public class Document extends BaseEntity{
private Connector connector;//
}
public class Connector extends BaseEntity{
}
public abstract class BaseEntity implements Serializable {
private T id;
}
Currently, when deep-mapping is used for a field, Dozer creates empty objects in destination hierarchy, instead of copying "null" from source to destination.
This behaviour looses relevant information : "null" means that no child objects are defined, which is different from a "empty" object (object with default values for all fields).
Fix : in method "writeDeepDestinationValue", the "destFieldValue" argument should be checked for null value.
Currently, the code in EnumConverter works like this:
return Enum.valueOf(destClass, srcObj.toString());
This is not quite correct if srcObj is an Enum. I suggest that code should be like this:
if (srcObj instanceof Enum) {
return Enum.valueOf(destClass, ((Enum) srcObj).name());
}
return Enum.valueOf(destClass, srcObj.toString());
Recently I have discovered issues with private constructors for our [widely used, large] API that does not work well with Dozer (because you cannot instantiate these objects outside of the API package). The solution was to ignore a property because essentially it was not needed (a web service to API mapping). The problem is that this STILL generates errors. Below is the error and the config xml I am using.
2013-01-18 15:18:57,631 ERROR [pool-nmr.endpoint.TaskWS/1.1/Port-thread-1] com.X.webservices.common.BaseWS: service name: updateMultipleTasksRequest Exception occured in TaskWSImp.updateMultipleTasksRequest() com.X.webservices.beans.order.Memo cannot be cast to com.X.Y.busobj.memo.Memo --java.lang.ClassCastException: com.X.webservices.beans.order.Memo cannot be cast to com.X.Y.busobj.memo.Memo
<mapping>
<class-a>com.X.Y.busobj.order.Task</class-a>
<class-b>com.X.webservices.beans.order.OrderTask</class-b>
<field-exclude>
<a>remarks</a>
<b>remarks</b>
</field-exclude>
</mapping>
Please note that the remarks field is a List of type Memo (don't know if this matters). I do not understand why it is attempting to CAST anything? I've excluded the remarks field in the xml.
how can write general convertor for convert Enums from enum ordinal
i write this code but dose not work
plz help me plz ;
public class EnumCustomConverter implements CustomConverter {
@Override
public Object convert(Object destination, Object source, Class<?> destinationClass, Class<?> sourceClass) {
if(source == null)
return null;
if(destinationClass != null){
if(destinationClass.getSimpleName().equalsIgnoreCase("Integer")){
return this.getInteger(source);
}else if( destinationClass.isEnum()){
return this.getEnum(destinationClass, source);
}else{
throw new MappingException(
new StrBuilder("Converter").append(this.getClass().getSimpleName())
.append(" was used incorrectly. Arguments were: ")
.append(destinationClass.getClass().getName())
.append(" and ")
.append(source).toString());
}
}
return null;
}
private Object getString(Object object){
String value = object.toString();
return value;
}
private Object getEnum(Class<?> destinationClass, Object source){
Object enumeration = null;
Method [] ms = destinationClass.getMethods();
for(Method m : ms){
if(m.getName().equalsIgnoreCase("valueOfIndex")){
try {
enumeration = m.invoke( destinationClass.getClass(), (Integer)source);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
return enumeration;
}
}
return null;
}
private Integer getInteger( Object source){//enum
Integer enumeration = null;
Method [] ms = source.getClass().getMethods();
for(Method m : ms){
if(m.getName().equalsIgnoreCase("getIndex")){
try {
enumeration = (Integer)m.invoke( source);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
return enumeration;
}
}
return null;
}
}
public enum AccountStatus {
individual(0, "enter","\u0648\u0631\u0648\u062F"),//haghighi
juridical(1, "enter","\u0648\u0631\u0648\u062F");//hoghughi
private final Integer index;
private final String title;
private final String persianTitle;
AccountStatus(Integer index, String title,String persianTitle) {
this.index = index;
this.title = title;
this.persianTitle = persianTitle;
}
public Integer getIndex() { return index; }
public String getTitle() { return title; }
public String getPersianTitle() { return persianTitle; }
public static AccountStatus valueOfIndex(Integer index) {
for (AccountStatus type : values()) {
if (type.getIndex()==index) {
return type;
}
}
throw new IllegalArgumentException(
"Partnership status cannot be resolved for code " + index);
}
}
accountStatus accountStatusI have a list
List boList. I want to map it to ListdoList. But currently there is no support for this. I have to iterate over the first list and map each element and add it to the new list.
ArrayList objects = new ArrayList();
...
DozerBeanMapper MAPPER = new DozerBeanMapper();
...
ArrayList newObjects = MAPPER.map(objects, ...);
like this
<S, D> Collection map(Collection srcCollection, Class targetClass);
not iterate over list
We need to support code-based configuration for class-level custom converters
Put pledgie.com campain
//start
public enum AccountStatus {
individual(0, "enter"),//haghighi
juridical(1, "enter");//hoghughi
private final Integer index;
private final String title;
AccountStatus(Integer index, String title,String persianTitle) {
this.index = index;
this.title = title;
}
public Integer getIndex() { return index; }
public String getTitle() { return title; }
public static AccountStatus valueOfIndex(Integer index) {
for (AccountStatus type : values()) {
if (type.getIndex()==index) {
return type;
}
}
throw new IllegalArgumentException(
"Partnership status cannot be resolved for code " + index);
}
//end
how can map AccountStatus ---->Index;
how can map Index ---->AccountStatus;
how can map AccountStatus--->title;
It's my understanding that when the is-accessible="true"
settings is applied at the class level this should result in private fields (without getters / setters) being mapped.
For example, the following mapping...
<mapping>
<class-a is-accessible="true">com.example.Foo</class-a>
<class-b is-accessible="true">com.example.FooDTO</class-b>
</mapping>
...should result in the private fields of Foo
being mapped to FooDTO
and visa versa. But the above does not work with Dozer 5.3.2.
However, when the individual fields of Foo
and FooDTO
are specified and is-accessible="true" is applied at the field-level the private fields are mapped correctly.
Please correct me if my understanding of how is-accessible="true"
when applied at the class level is incorrect.
Dozer should perform automatic Enum to int (Integer) and back mapping by enum's ordinal value.
hello,
i am trying to find dozer 5.4 in a public repository but could only find 5.3.2 there. are you planning to upload dozer to eg. sonatype nexus?
I get this exception "org.dozer.MappingException: More than one global configuration found", but there is only one dozerMapping.xml in each ear. None in any of the jars or the shared libs. I am running dozer 5.2
Thanks
Jacob
Migrate from sourceforge to GitHub.
OSGi is highly modular environment and there are a lot of OSGi containers like apache-karaf, apache-servicemix, jboss, eclipse virgo, paremus service fabric, etc.
These containers behave like application containers, i.e. we are able to deploy OSGi bundles like ordinary applications into them.
It's often necessary to have separate applications which use conversions (by means of dozer) and which must be isolated, versioned, etc. So they need completely separate dozer configurations per bundle.
Currently it's hardly possible because of class loading issues and a lot of singletons (DozerInitializer, GlobalSettings, BeanContainer, GlobalStatistics, etc.) in the dozer. That means that all these singletons are shared across all OSGi bundles. It's also hardly possible to specify correct classloader of the bundle (because BeanContainer is singleton).
It's seems that some kind of refactoring is needed to remove all these singletons.
Will the dozer be supported in the future? It seems that these great project becomes not very active.
In a MapperAware custom converter, if you map an object and then try to map the object a second time without specifying the destination class you get a NPE at MappedFieldsTracker:55 on destType
MappingProcessor:151, destClass should be destType since destClass may be null if the class isn't specified
Example (in a MapperAware class):
A a = new A();
B b = new B();
mapper.map(a, b);
B b2 = new B();
mapper.map(a, b2); //throws NPE
Following is the test case.
B.getVar returning int
C.setVar accepting Integer
//--
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.junit.Assert;
import org.junit.Test;
/**
* Verify the mapper
*/
public class TestMapper {
public static class B {
public B() {
}
public B(int var) {
this.var = var;
}
private int var;
public int getVar() {
return var;
}
public void setVar(int var) {
this.var = var;
}
}
//field is Integer, and setter needs Integer.
public static class C {
public C() {
}
private Integer var;
public C(int var) {
this.var = var;
}
public int getVar() {
return var;
}
public void setVar(Integer var) {
this.var = var;
}
}
@Test
public void testMapping() {
Mapper mapper = new DozerBeanMapper();
B b = new B(100);
C c = mapper.map(b, C.class);
Assert.assertEquals(100, c.getVar()); //test failure
}
}
I've implemented a custom converter:
@Override
public ConfigurationGroupInfo convertTo(ConfigurationGroup source, ConfigurationGroupInfo destination) {
ConfigurationGroupInfo configurationGroupInfo = new ConfigurationGroupInfo();
copyProperties(source, configurationGroupInfo);
setLocationConfigurationIds(source, configurationGroupInfo);
return configurationGroupInfo;
}
After the custom converter has finished converting, the MappingProcessor seems to continue to map the individual fields on my source object, overwriting the work of the custom converter. This is how I am setting up the customConverter:
<mapping>
<class-a>com.tlcdelivers.ls2pac.model.entity.ConfigurationGroup</class-a>
<class-b>com.tlcdelivers.indigo.model.view.ConfigurationGroupInfo</class-b>
<field custom-converter="com.tlcdelivers.ls2pac.util.ConfigurationGroupConverter">
<a>this</a>
<b>this</b>
</field>
</mapping>
In looking at the MappingProcessor, it seems as if it should be using this:
if (converterClass != null) {
return (T) mapUsingCustomConverter(converterClass, srcObj.getClass(), srcObj, destType, result, null, true);
}
But instead is proceeding to line 187 in a call to:
map(classMap, srcObj, result, false null);
Any ideas?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.