Dozer mapping issue with 1:1 conversion - dozer

I'm getting this error while mapping these two fields. I've looked for documentation on how to map this from one object to the other, but there's very few documentation for the data type DurationImpl. The 1:1 mapping should be the same object type, but for some reason dozer isnt picking this up. Is there a way to override the source to the javax.xml.datatype.Duration type?
main ERROR org.dozer.MappingProcessor(283) - Field mapping error -->
MapId: null
Type: null
Source parent class: com.aa.flighthub.services.flightinfo.operational.messages.Times
Source field name: autoETDAccumMins
Source field type: class com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl
Source field value: PT0S
Dest parent class: com.aa.matrix.flightinfo.types.flightinfo.v1.Times
Dest field name: autoETDAccumMins
Dest field type: javax.xml.datatype.Duration

Well I finally figured out the error, so I implemented a custom dozer mapping to map this particular class. Once mapped using that method, the mapping went fine. Hopefully this helps someone in the future.

Related

MapStruct: Issue with Nested Properties and ReportingPolicy.ERROR on Unmapped Source Properties

Using MapStruct, we want to use ReportingPolicy.ERROR, and have code like the following:
#Mapping(source = "nestedSource.doublyNestedSourceField", target = "nestedTarget.doublyNestedTargetField")
Target mapSourceToTarget(Source source);
Where nestedSource is not the same type as nestedTarget, and both doublyNested*Field types are String.
There is no mapper declared for NestedSource -> NestedTarget. The String properties declared in the Mapping above are the only ones in those types.
The above causes an unmapped source error:
Unmapped source property: "doublyNestedSourceField".
That seems more-or-less reasonable, as we didn't declare a mapper for NestedSource -> NestedTarget.
However, here's the issue: If we change the ReportingPolicy for unmapped sources to warn/ignore, MapStruct figures out how to correctly map the doublyNestedSourceField in the mapper implementation, even though it claims there is no source mapping present. Just wondering what is going on here, and whether I'm missing something.
----Into the weeds a bit more (in the MapStruct code itself)----
I could be doing something wrong, but I did notice that in BeanMethodMapping.java MapStruct attempts to remove "nestedSource.doubleNestedSourceField" from unprocessedSourceProperties, even though the key for the appropriate property is just "nestedSource" in unprocessedSourceProperties. Thus "nestedSource" is left as an unprocessed source property and an error is thrown.

Disambiguate compiled classes in Spring Data

I am trying to use Spring to write a document in a MongoDB, and I am getting a org.springframework.data.mapping.MappingException: Ambiguous field mapping detected!
The problem is this ambiguity comes from a compiled class which inherits from another compiled class, so I can not use #Field annotation to change the field name manually.
Is there any way to tell Spring how to resolve ambiguous field mappings without modifying the classes' code?
The class I am trying to persist looks like this:
data class BehaviouralEvent(
val sources: Set<BehaviouralEvent>,
override val activity: Activity,
override val start: Instant = Instant.now(),
override val end: Instant = Instant.now(),
override val lifecycle: Lifecycle = Lifecycle.UNKNOWN
) : Event(activity, start, end, lifecycle) {
constructor(
sources: Set<BehaviouralEvent>,
activityID: String,
start: Instant = Instant.now(),
end: Instant = Instant.now(),
lifecycle: Lifecycle = Lifecycle.UNKNOWN
) : this(sources, Activity.from(activityID), start, end, lifecycle)
constructor(
sources: Set<BehaviouralEvent>,
event: Event
) : this(sources, event.activity, event.start, event.end, event.lifecycle)
}
When I try to persist a document with this structure (with a MongoRepository<BehaviouralEvent, String>) I get an ambiguous field mapping for all the overridden attributes (activity, start, end and lifecycle).
Appreciate any ideas or workarounds.
tl;dr At the time of writing there is no way around this issue.
The mapping layer currently has no means to tell which of the properties should be persisted if one "shadows" the other. Therefore we have this check in the entity metadata.
Now, if you tried to relax the unique field check in BasicMongoPersistentEntity a bit for Kotlin types by adding someting like
if(isKotlinType(property.getOwner()) && !propety.hasGetter()) {
return;
}
the repository will no longer complain at creation time. However, the mapping layer still needs to determine which of the presented properties to persist as depending on inspection order, they still override one another and it's likely one ends up with the wrong state persisted. Especially when overriding val with var.
I've opened DATAMONGO-2250 to investigate further and see if there's something we can do about it.

Core Data: Could not cast value of type 'MyType_MyType_2' to MyType

I have an Objective-C model class MyType. This class is used in Swift code:
NSEntityDescription.insertNewObjectForEntityForName("MyType", inManagedObjectContext: context) as! MyType
The as! cast results in the error message
Core Data: Could not cast value of type 'MyType_MyType_2' (0x7be99a30) to MyType (0xf33db74).
If I cast it as NSManagedObject it works. When I print the result, I can nevertheless see, that it is an actual instance of MyType:
<MyType: 0x7ae06d50> (entity: MyType; id: 0x7aeba6d0 <x-coredata:///MyType/t957F2860-85F8-46E0-B6D6-4D1DF6C4EC613> ; data: {
...the fields...
})
What is happening here? And where does the name MyType_MyType_2 come from?
When I had this issue, it was because I had forgotten to set the "class" on the entity. This is what I came up with:
Click on .xcdatamodelId file in your file structure/project
navigator pane (far left).
Select the entity that you are having issues with.
In the Utilities pane (far right), look for the icon that looks like a 1997 cell phone, the Data Model Inspector.
Under the entity settings, you should see two fields, "Name" and "Class" - set up "Class" with the name of the class you are using (typically the same as "Name").
You'll even notice before you follow these steps that the default "class" is NSObject, reflecting the error message. I found some programatic ways to do this too, but this seemed like the simplest/quickest solution.
I should note that my model WAS written in Swift, so I did have to add the #objc(Entity) interoperability reference mentioned by #zellb. But that shouldn't make a difference in the solution as long as you are doing that part properly (and that would cause a different unrelated error from my understanding).
Set Entity Class Name
Set Module "Current Product Module" like below
just try this:
#objc(MyType)
public class MyType: NSManagedObject {
// your class
}
instead of this:
class MyType: NSManagedObject {
// your class
}
I had mistakenly set a "parent entity" in one of my entities in the data model inspector in the entity section. I mistakenly thought that referred to the destination of a one-to-many relationship.
Setting it back to "no parent entity" fixed the problem, although I did have to delete and reinstall the app in the simulator to deal with the messed up core data database.

What is the "Func<object> modelAccessor" parameter for in MVC's DataAnnotationsModelMetadataProvider?

It's one of the parameters supplied to the CreateMetadata method (which you override if extending metadata support).
ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor, <<--THIS ONE
Type modelType,
string propertyName)
I had assumed that it allowed you to access the model object itself (e.g. for setting metadata based on model values), however when I try to use it to cast to my model object I just get null.
Entity ent = (Entity)modelAccessor(); // = Null
If I've missunderstood, can anyone explain what it's purpose is? Or alternatively, how to properly use it?
Thanks
We originally had that as "object model", rather than "Func modelAccessor". We had to change it late in MVC 2's ship cycle.
The purpose is to delay retrieving the actual value of the model until such point as you know you're going to need it (that is, until you call ModelMetadata.Model).
The problem it solves is actually a rather esoteric one related to model binding against a LINQ to SQL class that has a foreign key reference in it. The problem is, if you've retrieved the child object which is represented by a foreign key relationship (which usually means a delay load of that object), then you're no longer allowed to choose a new child object by setting the foreign key ID property. It's very common to model bind the foreign key ID (and not the whole foreign key entity) when model binding, but if we'd retrieved the foreign key entity object (for the purposes of populating the ModelMetadata class) then that binding would no longer be legal, and actually throw an exception. Since ModelMetadata is used for both directions of models -- inbound, via model binding, and outbound, via HTML generation -- we needed to introduce the layer of indirection to protect your ability to use it in both scenarios without disrupting LINQ to SQL's rules.
The modelAccessor parameter does not point to an instance of the object, but rather it is a function that will access some attribute of your object. The Func "encapsulates a method that has no parameters and returns a value of the type specified by the TResult parameter." For example, if we have following class:
public class Bar(){
[DisplayName("I am Foo.")]
public string Foo{get;}
}
When the CreateMetaData is called, it will be to create meta data for the Foo property and the modelAccessor will be a function that returns the value of Foo.
I did a little digging and found a way to get to the instance of the object, but it requires using reflection. You can do the following to get the Bar class in my example:
if (modelAccessor != null)
{
//Use reflection to get the private field that holds the Bar object.
FieldInfo container = modelAccessor.Target.GetType().GetField("container");
//Invoke field on the modelAccessor target to get the instance of the Bar object.
Bar myObject = (Bar)container.GetValue(modelAccessor.Target);
}
I've only run this against a simple test case, so your mileage may vary, but hopefully this will help clarify what is going on.

Entity Framework 4.0: Create an unmapped property in the model (currenty i get : error 11009 - Property is not mapped)?

I know that i can enter/add new properties via code manually into partial classes but i wanted to use the model to add my new properties - reason being is that i can control a number of different attributes like NULL and things like that... and of course the code generations works great..
I added some foreign keys manually just on the model and they work great.
But everytime i add a SCALER PROPERTY i get an error in vs 2010 which says
Error 2538 Error 11009: Property 'testprop' is not mapped.
I can't believe i must map a custom property that i created to a column in the db.... is there no way to say "IGNORE" this property or treat as an unmapped property??
This way my code generation will create the required items BUT i don't get the error
Any help on this would be really helpful.
As i say i know i can edit things manually but wanted to update the model rather than edit a partial class....
I am sure i am missing something obvious?
With EntityFramework 5 you can use the NotMappedAttribute for unmapped properties. So, you can migrate to EF5 or use partial classes on EF4.
I believe that EF will on allow you to use the Model Designer to map to something that exists. If you want to create a property that doesnt exist, you'll have to use the partial class.
I had the same error - you can use the NotMappedAttribute for unmapped properties...