[ 
https://issues.apache.org/jira/browse/JDO-751?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15152861#comment-15152861
 ] 

Craig L Russell edited comment on JDO-751 at 2/19/16 4:31 AM:
--------------------------------------------------------------

Here's another try at a solution. 

Optional<T> is a Java domain modeling concept that is loosely followed in JDOQL 
to track the semantics but not necessarily the syntax.

Optional<Optional<T>> is disallowed. If anyone can give a real example, I will 
listen.

Mapping a persistent field of type Optional<T> requires that the mapped 
database field be nullable.

Add Optional as a JDOQL feature and allow methods get() and isPresent() to be 
used with JDOQL. Consider adding .equals to this but only if we can't figure 
out how to compare to null, other Optional<T>, and primitive/boxed values.

To make it easier to express in JDOQL, assume a simple domain model with a 
class Person with a field age of type Optional<Integer> and field address of 
type Optional<Address>. Address contains String city, String state, String 
postalCode. The query is on class Person. The following are equivalent in JDOQL:
{address!=null is equivalent to address.isPresent()}
address.city=="New York" is equivalent to address.get().city=="New York"
address.city=="New York" is equivalent to (address.isPresent() && 
address.get().city=="New York")
address==null is equivalent to (!address.isPresent())
age==null is equivalent to !age.isPresent()
age==7 is equivalent to (age.isPresent() && age.get()==7)
age==7 is equivalent to (age.get()==7)

If using the result feature of JDOQL, specifying the result to be address, the 
type of the return value is Optional<Address>. 

Parameters can be passed as type Optional. 
setParameters("Optional<Integer> paramOptInteger, Integer paramInteger, int 
paramInt")

The following are equivalent in JDOQL:
age==paramInt is equivalent to (age.isPresent() && age.get()==paramInt)
age==paramInteger is equivalent to (age.isPresent() && age.get()==paramInteger)
age==paramOptInteger is equivalent to (age.isPresent() && paramOptInt.isPresent 
&& 
    age.get()==paramOptInteger)| ( ( 
!age.isPresent())&&!(paramOptInteger.isPresent())
^^^ I think the above makes the case for auto-boxing parameters and fields

I did not see anything in the current specification that allows passing domain 
objects as parameters, so it's unnecessary to discuss passing Optional<Address> 
as parameters.

Other comments from discussion above:

I agree that there is a difference between null and empty, but it doesn't have 
to matter. When we persist an object where the address field is null, we store 
null in the datastore. If the address field is Optional.EMPTY, we store null in 
the datastore. When we retrieve the object from the datastore, the Optional 
will always be non-null.

MemberMetadata.getFieldType should return "Optional<Address>". I don't see the 
problem with type erasure, since the metamodel uses strings to represent types.




was (Author: clr):
Here's another try at a solution. 

Optional<T> is a Java domain modeling concept that is loosely followed in JDOQL 
to track the semantics but not necessarily the syntax.

Optional<Optional<T>> is disallowed. If anyone can give a real example, I will 
listen.

Mapping a persistent field of type Optional<T> requires that the mapped 
database field be nullable.

Add Optional as a JDOQL feature and allow methods get() and isPresent() to be 
used with JDOQL. Consider adding .equals to this but only if we can't figure 
out how to compare to null, other Optional<T>, and primitive/boxed values.

To make it easier to express in JDOQL, assume a simple domain model with a 
class Person with a field age of type Optional<Integer> and field address of 
type Optional<Address>. Address contains String city, String state, String 
postalCode. The query is on class Person. The following are equivalent in JDOQL:
address!=null is equivalent to address.isPresent()
address.city=="New York" is equivalent to address.get().city=="New York"
address.city=="New York" is equivalent to (address.isPresent() && 
address.get().city=="New York")
address==null is equivalent to (!address.isPresent())
age==null is equivalent to !age.isPresent()
age==7 is equivalent to (age.isPresent() && age.get()==7)
age==7 is equivalent to (age.get()==7)

If using the result feature of JDOQL, specifying the result to be address, the 
type of the return value is Optional<Address>. 

Parameters can be passed as type Optional. 
setParameters("Optional<Integer> paramOptInteger, Integer paramInteger, int 
paramInt")

The following are equivalent in JDOQL:
age==paramInt is equivalent to (age.isPresent() && age.get()==paramInt)
age==paramInteger is equivalent to (age.isPresent() && age.get()==paramInteger)
age==paramOptInteger is equivalent to (age.isPresent() && paramOptInt.isPresent 
&& 
    age.get()==paramOptInteger)| ( ( 
!age.isPresent())&&!(paramOptInteger.isPresent())
^^^ I think the above makes the case for auto-boxing parameters and fields

I did not see anything in the current specification that allows passing domain 
objects as parameters, so it's unnecessary to discuss passing Optional<Address> 
as parameters.

Other comments from discussion above:

I agree that there is a difference between null and empty, but it doesn't have 
to matter. When we persist an object where the address field is null, we store 
null in the datastore. If the address field is Optional.EMPTY, we store null in 
the datastore. When we retrieve the object from the datastore, the Optional 
will always be non-null.

MemberMetadata.getFieldType should return "Optional<Address>". I don't see the 
problem with type erasure, since the metamodel uses strings to represent types.



> Support for Java8 Optional
> --------------------------
>
>                 Key: JDO-751
>                 URL: https://issues.apache.org/jira/browse/JDO-751
>             Project: JDO
>          Issue Type: New Feature
>          Components: specification, tck
>            Reporter: Andy Jefferson
>
> java.util.Optional provides a feature that is available in other languages. 
> Since JDO 3.2 will be for Java8+ then it makes sense to add support for this 
> as a "supported persistable type"



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to