[ 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:32 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)