-
Notifications
You must be signed in to change notification settings - Fork 268
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 it's 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-defind/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 ).
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 antoher. 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.
Is an explicitly registered mapping definition bi-directional, or do I need to define it in both directions?
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.
How can I tell what Orika is doing at runtime? (Which mappers are registered, how did it resolve my request to a particular mapper/converter/etc., when and how did it auto-generate a mapping?)
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.2.0</version>
</dependency>
Orika does not currently support this by default, but it can be achieved using a custom converter (by extending ma.glasnost.orika.CustomConverter or ma.glasnost.orika.converter.BidirectionalConverter).
Can I map fields that don't have corresponding getter/setter methods, or call non-public constructors?
Orika will allow mapping of public fields as properties, 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.
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.
A Mapper is used for applying the properties of an object of one type to an object of another type. An ObjectFactory? is used for constructing an instance of a particular destination type, in the context of mapping from a particular source type. A Converter is used to completely take over the mapping process for a particular set of types.
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.2.0</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.2.0</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)