NPE on MapKey maps

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

NPE on MapKey maps

pveselov
Hello.

I ran into this problem, and I'm not sure what the right answer is.
Consider just two entities (I've gutted them to the pieces that are
relevant, I tried this on corresponding classes in
org.apache.openjpa.persistence.relations package,
openjpa-persistence-jdbc module):

public class MapKeyParent implements Serializable {
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch =
FetchType.EAGER)
    @MapKey(name = "mapKey")
    private Map<String, MapKeyChild> children;
}
public class MapKeyChild implements Serializable {
    @ManyToOne @JoinColumn private MapKeyParent parent;
}

Creating the entities separately, and flushing them causes an NPE
(https://pastebin.com/StN604Hg):

        MapKeyParent parent = new MapKeyParent();
        MapKeyChild child = new MapKeyChild();
        child.setParent(parent);
        em.persist(parent);
        em.persist(child);
        em.flush();

The NPE is obviously because parent.children is null. But should this
be considered a problem? Is there a rule that says that I have to
reference children in the corresponding collections/maps (I never had
to do it before)? If it is not required, how can this be fixed?

I can't quite understand what is the point of
RelationFieldStrategy.setMapKey() method. It seems that it may not do
well if map, or the key is null. Also, I'm rather bothered by the fact
that map key is searched in the map by iterating over the map values,
and even it's not needed (i.e. when key is not embedded and strategy
is not HandlerRelationMapTableFieldStrategy).

An obvious "fix" for me, is to either add the object to children map,
or at least have the map empty by the time flush() is called. I don't
see any adverse effects on sending the data to the storage.

Thank you,
  Pawel.
Reply | Threaded
Open this post in threaded view
|

Re: NPE on MapKey maps

Matthew Broadhead-2
If it is set to cascade then this should work?
MapKeyParent parent = new MapKeyParent();
parent.setChildren(new ArrayList<>());
MapKeyChild child = new MapKeyChild();
child.setParent(parent);
parent.getChildren().add(child);
em.persist(parent);
em.flush();


On 08/09/18 02:42, Pawel Veselov wrote:

> Hello.
>
> I ran into this problem, and I'm not sure what the right answer is.
> Consider just two entities (I've gutted them to the pieces that are
> relevant, I tried this on corresponding classes in
> org.apache.openjpa.persistence.relations package,
> openjpa-persistence-jdbc module):
>
> public class MapKeyParent implements Serializable {
>      @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch =
> FetchType.EAGER)
>      @MapKey(name = "mapKey")
>      private Map<String, MapKeyChild> children;
> }
> public class MapKeyChild implements Serializable {
>      @ManyToOne @JoinColumn private MapKeyParent parent;
> }
>
> Creating the entities separately, and flushing them causes an NPE
> (https://pastebin.com/StN604Hg):
>
>          MapKeyParent parent = new MapKeyParent();
>          MapKeyChild child = new MapKeyChild();
>          child.setParent(parent);
>          em.persist(parent);
>          em.persist(child);
>          em.flush();
>
> The NPE is obviously because parent.children is null. But should this
> be considered a problem? Is there a rule that says that I have to
> reference children in the corresponding collections/maps (I never had
> to do it before)? If it is not required, how can this be fixed?
>
> I can't quite understand what is the point of
> RelationFieldStrategy.setMapKey() method. It seems that it may not do
> well if map, or the key is null. Also, I'm rather bothered by the fact
> that map key is searched in the map by iterating over the map values,
> and even it's not needed (i.e. when key is not embedded and strategy
> is not HandlerRelationMapTableFieldStrategy).
>
> An obvious "fix" for me, is to either add the object to children map,
> or at least have the map empty by the time flush() is called. I don't
> see any adverse effects on sending the data to the storage.
>
> Thank you,
>    Pawel.

Reply | Threaded
Open this post in threaded view
|

Re: NPE on MapKey maps

Matthew Broadhead-2
sorry i missed the point about the mapkey.

On 08/09/18 10:26, Matthew Broadhead wrote:

> If it is set to cascade then this should work?
> MapKeyParent parent = new MapKeyParent();
> parent.setChildren(new ArrayList<>());
> MapKeyChild child = new MapKeyChild();
> child.setParent(parent);
> parent.getChildren().add(child);
> em.persist(parent);
> em.flush();
>
>
> On 08/09/18 02:42, Pawel Veselov wrote:
>> Hello.
>>
>> I ran into this problem, and I'm not sure what the right answer is.
>> Consider just two entities (I've gutted them to the pieces that are
>> relevant, I tried this on corresponding classes in
>> org.apache.openjpa.persistence.relations package,
>> openjpa-persistence-jdbc module):
>>
>> public class MapKeyParent implements Serializable {
>>      @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch =
>> FetchType.EAGER)
>>      @MapKey(name = "mapKey")
>>      private Map<String, MapKeyChild> children;
>> }
>> public class MapKeyChild implements Serializable {
>>      @ManyToOne @JoinColumn private MapKeyParent parent;
>> }
>>
>> Creating the entities separately, and flushing them causes an NPE
>> (https://pastebin.com/StN604Hg):
>>
>>          MapKeyParent parent = new MapKeyParent();
>>          MapKeyChild child = new MapKeyChild();
>>          child.setParent(parent);
>>          em.persist(parent);
>>          em.persist(child);
>>          em.flush();
>>
>> The NPE is obviously because parent.children is null. But should this
>> be considered a problem? Is there a rule that says that I have to
>> reference children in the corresponding collections/maps (I never had
>> to do it before)? If it is not required, how can this be fixed?
>>
>> I can't quite understand what is the point of
>> RelationFieldStrategy.setMapKey() method. It seems that it may not do
>> well if map, or the key is null. Also, I'm rather bothered by the fact
>> that map key is searched in the map by iterating over the map values,
>> and even it's not needed (i.e. when key is not embedded and strategy
>> is not HandlerRelationMapTableFieldStrategy).
>>
>> An obvious "fix" for me, is to either add the object to children map,
>> or at least have the map empty by the time flush() is called. I don't
>> see any adverse effects on sending the data to the storage.
>>
>> Thank you,
>>    Pawel.
>