Of course! If you mapped these objects by hand, you would write a unit test, right? So you’re just going to trust us that we mapped your objects the way you expected us to? That’s giving Orika and its authors a little too much credit. Please write tests to confirm the objects are mapped as you expect.
Orika uses reflection to access data object properties, and by default is designed to read object properties that conform to the JavaBeans standard. This means that an object with ‘getName’ and/or ‘setName’ methods would be said to have a property called ‘name’; the ‘setXXX’ method is not required, and for (primitive) boolean return types, the ‘getXXX’ method can optionally be named ‘isXXX’ instead.
Orika takes this a little bit further, including java.lang.Boolean types for the optional ‘isXXX’ naming, and Orika will also recognize public fields as properties to be used.
Yes. Most scenarios are supported by default, including primitives, primitive wrappers, Enums, Collections, Arrays, Maps, and Complex types.
There are an additional set of converters for numeric and date types which can be enabled by calling the useBuiltinConverters(true) on DefaultMapperFactory.Builder.
Additionally, it is straightforward to register a custom mapper (by `extending ma.glasnost.orika.CustomMapper`) to deal with a conversion that is not built-in.
Orika has a base set of types which it treats as immutable, i.e., that are copied by reference from the source to the destination. Specifically, that list includes all of the primitive types and their corresponding wrapper classes, String, BigDecimal, etc.
User-defined/declared immutable types are possible via the registration of a special Converter (PassThroughConverter).
Yes; when a mapping is requested for 2 types which have not been explicitly registered. When registering an explicit mapping from one type to another, Orika will do this only if the ‘byDefault’ method is called on the fluent-style ClassMapBuilder API.
Yes. Any number of DefaultFieldMapper instances can be defined/registered which are consulted for a default mapping, in the case where a matching field could not be found for a given property. Additionally, the default mapping behavior can be completely customized by extending ClassMapBuilder (see [issue 33](https://code.google.com/p/orika/issues/detail?id=33)).
Yes. Orika will continue to map nested classes until mapping is completed with a “simple” type. It also contains fail-safes to properly deal with recursive references within the objects you’re attempting to map.
Orika uses reflection to investigate the metadata of the objects to be mapped and then generates byte-code at runtime which is used to map those classes. This means that although some initial overhead is incurred to investigate the types and generate the mappers, the overall runtime performance is comparable to mapping by hand.
Yes. Orika automatically maps between compatible multi-occurrence types (Arrays and java.util.Collection types, or between Map types) and automatically performs the necessary type conversions; mapping between Arrays, Collections, and Maps can be declared using the ClassMapBuilder API.
Yes. Orika will reuse mappers already defined for a given class hierarchy, and you can customize it using `ClassMapBuilder.use`
Yes. Orika includes special runtime support for the mapping of generic types via a special Type<?> class which can be used to define the exact type elements of a templated type.
Yes. Orika has support for the registration of a “concrete” type for a given abstract/interface type, including a default registration for the common Map and Collection types.
Orika mapping is configured via Java code at runtime, via a fluent-style ClassMapBuilder API. An instance is obtained from a MapperFactory which is then used to describe the mapping from one type to another. Finally, the specified ClassMap is registered with the MapperFactory for later use in generating a byte-code mapper.
The recommended way to configure orika is by extending `ma.glasnost.orika.impl.ConfigurableMapper`, and providing any necessary customizations/configurations in the `configure` and `configureFactoryBuilder` methods; an instance of that custom mapper can then be safely shared as a singleton.
Yes. The best option is to define your own sub-class of ConfigurableMapper (as mentioned above) in singleton scope.
Ideally, most of your field mappings can be performed automatically; for the exceptions, a custom mapping can be registered.
Using an extension of ConfigurableMapper (as mentioned above), the configure() method is where this should be done.
Yes; registered (and automatically generated) mappings are bi-directional by default.
When defining a mapping, instead of using the `field(“fieldA”,“fieldB”)` method, use one of `fieldAToB(“fieldA”,“fieldB”)` or `fieldBToA(“fieldB”,“fieldA”)` to register a mapping in a single direction.
Simply enable DEBUG logging for “ma.glasnost.orika” logger; Orika uses the Slf4J logging API, so should be compatible with most logging implementations if using an appropriate logging bridge.
1.5 and above.
Yes.
<dependency> <groupId>ma.glasnost.orika</groupId> <artifactId>orika-core</artifactId> <version>1.3.1</version> </dependency>
Yes. (as of version 1.3.0)
For a Bean to Map, simply define your class-map as normal using the mapperFactory.classMap(...)
method, passing one of the types as a Class<?>
(or Type<?>
) which is assignable to java.util.Map
. The field-names on the Map side of the equation will be used as the Map keys.
Using the byDefault()
method in such a scenario would result in all the properties of the Bean type being mapped by their property name into the Map type.
For a Bean to List or Array, follow the same strategy as mentioned above for Maps, but instead of providing key values, you would instead provide index values within the Array or List at which the Bean values should be stored.
Orika will allow mapping of public fields as properties by default, but otherwise, the mapping of inaccessible fields is not supported.
Since Orika generates Java code to perform the actual mapping, it will generally follow the same restrictions of what you could write yourself.
Since Orika generates Java code to perform the actual mapping, it will generally follow the same restrictions of what you could write yourself. So by default, this is not supported; but you could accomplish this via a special ObjectFactory or Converter which obtains a reference to the constructor (via reflection) marks it accessible, and then invokes it to create an instance (or some other similar approach).
Yes. Enum instance are automatically mapped based on their instance values (when not of the same enumeration).
Use the ma.glasnost.orika.metadata.Type<?> construct to pass the runtime type into a given map method.
Orika mappings can be customized by creating your own custom Converters, Mappers, and ObjectFactory types. See the question below for information on what the different constructs are used for and which you might need.
To show debug logging information about the mappings used, generated, and the types resolved, set the “ma.glasnost.orika” package to DEBUG logging level.
To step-debug (in Eclipse or other IDE) into the actual generated classes, you’ll first need to include the ‘orika-eclipse-tools’ jar in your project.
<dependency> <groupId>ma.glasnost.orika</groupId> <artifactId>orika-eclipse-tools</artifactId> <version>1.3.1</version> <scope>test</scope> </dependency>
Note that Orika makes use of Eclipse JDT independent of any containing Eclipse runtime environment
We recommend including this at ‘test’ scope if using Maven. Then, you can enable use of the EclipseJdtCompilerStrategy.class by setting the following system property value:
-Dma.glasnost.orika.compilerStrategy=ma.glasnost.orika.impl.generator.EclipseJdtCompilerStrategy
This will tell Orika to use EclipseJdt to compile and format the generated mapper objects with debug information which is necessary for step-debugging.
Then, you’ll need to add a File System folder to your debug source which includes your project’s binary output location (if using Maven, this would be the ‘target/classes’ and ‘target/test-classes’ folders).
Note that it cannot be a workspace reference, since the generated classes won’t be known to Eclipse until after the test VM has been launched.
Yes. The reason it is not the default has mostly to do with size and number of additional jars required.
Runtime performance has been roughly equivalent to the Javassist strategy in tests thusfar, but you will want to disable the automatic writing of class and source files to disk by setting the following system properties (which default to ‘true’ in the EclipseJDt strategy):
-Dma.glasnost.orika.writeSourceFiles=false -Dma.glasnost.orika.writeClassFiles=false
You will first need to make sure to include the ‘orika-eclipse-tools’ jar in your project’s dependencies.
<dependency> <groupId>ma.glasnost.orika</groupId> <artifactId>orika-eclipse-tools</artifactId> <version>1.3.1</version> </dependency>
To enable/specify this compiler strategy, the best option is to specify it in the `configureFactoryBuilder` method of your extension of `ConfigurableMapper`, like so:
public void configureFactoryBuilder(DefaultMapperFactory.Builder builder) { builder.compilerStrategy(new EclipseJdtCompilerStrategy()); }
A less-preferable option is to specify the system property (as mentioned in the above question about debugging Orika)