Lazy Loading of an attribute leading to a null pointer exception - spring

I have an attribute inside my entity which is being loaded in a lazy way, this property itself could be null hence I cant directly go ahead and perform any operation on this and also since this is lazy loaded, a null check is not helping me out.
Example :
parent.getChild().getContent() != null
here my child is lazy laoded, and there is a chance that getChild would itself return me null hence getContent() will lead to NPE.
putting a null check above this line of code would also not help as parent.getChild() would be null as this is lazy loaded initially.

Since lazy-loading will occur when you call getChild(), before the null-check is executed, this will not be an issue. Do your null-check as you need it to be, getChild() will only return null if it is actually null.

Related

How to find out if key exist in cacheManager (org.springframework.cache.CacheManager)

Is there a way to see if a particular key exist in cacheManager (org.springframework.cache.CacheManager) as i am unable to find a way to do that as there is no containsKey option. I would appreciate if someone could show me a way to check if a key exist in cacheManager. Below are few things i have tried so far -
Cache cache=null;
for (String name : cacheManager.getCacheNames()) {
cache=cacheManager.getCache(name);
System.out.println("-------------->"+cache.get("dummyCache").get()); //this will give me null pointer exception as there is no dummyCache
}
I would like add if/else check to see if a dummyCachekey exist in cache
You can simply check the value returned by Cache.get for null.
From the relevant documentation (emphasis by me):
Returns the value to which this cache maps the specified key, contained within a Cache.ValueWrapper which may also hold a cached null value. A straight null being returned means that the cache contains no mapping for this key.
So
cache.get("foo") == null means: The key "foo" does not exist in the cache
cache.get("foo").get() == null means: The key "foo" does exist in the cache, but its value is null

Java 8 Guava Preconditions throwing NullPointerException while evaluating the exception message string

I have an object myObject and I want to make sure that it is null or else I want to print a custom message with the object's id. I have the following line of code trying to achieve the same
Preconditions.checkArgument(Objects.isNull(myObject),
"This object is not null #%s.", myObject.getId());
This condition works fine when myObject is not null. It throws the appropriate exception message. But when the object is indeed null, it was my expectation that the rest of the code would be executed but instead, I get a null pointer exception because of myObject.getId() call.
Do guava preconditions evaluate the exception message string regardless of whether the condition is true or not?
With
Preconditions.checkArgument(Objects.isNull(myObject),
"This object is not null #%s.", myObject.getId());
you have to look what happens in which order:
Before any call to checkArgument() can occur, all arguments to it are evaluated:
Objects.isNull(myObject)
the string
myObject.getId()
Only then the call can occur, and if an exception occurs during this evaluation, the call doesn't happen at the first place.
Just for completeness, as it was already mentioned elsewhere: the way to go would be myObject == null ? null: myObject.getId(), as it avoids the dereferencing in the case of a null object.
You could hack it via (for example):
static void test(Object myObject) {
Preconditions.checkArgument(
myObject == null, "This object is not null #%s.", myObject == null ? null : myObject.getId()
);
}
The condition: myObject == null ? myObject : myObject.hashCode() is still going to be evaluated, always; but the error Message itself will not be computed until needed.

Sense of Optional.orElse() [duplicate]

Why does this throw a java.lang.NullPointerException?
List<String> strings = new ArrayList<>();
strings.add(null);
strings.add("test");
String firstString = strings.stream()
.findFirst() // Exception thrown here
.orElse("StringWhenListIsEmpty");
//.orElse(null); // Changing the `orElse()` to avoid ambiguity
The first item in strings is null, which is a perfectly acceptable value. Furthermore, findFirst() returns an Optional, which makes even more sense for findFirst() to be able to handle nulls.
EDIT: updated the orElse() to be less ambiguous.
The reason for this is the use of Optional<T> in the return. Optional is not allowed to contain null. Essentially, it offers no way of distinguishing situations "it's not there" and "it's there, but it is set to null".
That's why the documentation explicitly prohibits the situation when null is selected in findFirst():
Throws:
NullPointerException - if the element selected is null
As already discussed, the API designers do not assume that the developer wants to treat null values and absent values the same way.
If you still want to do that, you may do it explicitly by applying the sequence
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
to the stream. The result will be an empty optional in both cases, if there is no first element or if the first element is null. So in your case, you may use
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
.orElse(null);
to get a null value if the first element is either absent or null.
If you want to distinguish between these cases, you may simply omit the flatMap step:
Optional<String> firstString = strings.stream()
.map(Optional::ofNullable).findFirst().orElse(null);
System.out.println(firstString==null? "no such element":
firstString.orElse("first element is null"));
This is not much different to your updated question. You just have to replace "no such element" with "StringWhenListIsEmpty" and "first element is null" with null. But if you don’t like conditionals, you can achieve it also like:
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst()
.orElseGet(()->Optional.of("StringWhenListIsEmpty"))
.orElse(null);
Now, firstString will be null if an element exists but is null and it will be "StringWhenListIsEmpty" when no element exists.
You can use java.util.Objects.nonNull to filter the list before find
something like
list.stream().filter(Objects::nonNull).findFirst();
The following code replaces findFirst() with limit(1) and replaces orElse() with reduce():
String firstString = strings.
stream().
limit(1).
reduce("StringWhenListIsEmpty", (first, second) -> second);
limit() allows only 1 element to reach reduce. The BinaryOperator passed to reduce returns that 1 element or else "StringWhenListIsEmpty" if no elements reach the reduce.
The beauty of this solution is that Optional isn't allocated and the BinaryOperator lambda isn't going to allocate anything.
Optional is supposed to be a "value" type. (read the fine print in javadoc:) JVM could even replace all Optional<Foo> with just Foo, removing all boxing and unboxing costs. A null Foo means an empty Optional<Foo>.
It is a possible design to allow Optional with null value, without adding a boolean flag - just add a sentinel object. (could even use this as sentinel; see Throwable.cause)
The decision that Optional cannot wrap null is not based on runtime cost. This was a hugely contended issue and you need to dig the mailing lists. The decision is not convincing to everybody.
In any case, since Optional cannot wrap null value, it pushes us in a corner in cases like findFirst. They must have reasoned that null values are very rare (it was even considered that Stream should bar null values), therefore it is more convenient to throw exception on null values instead of on empty streams.
A workaround is to box null, e.g.
class Box<T>
static Box<T> of(T value){ .. }
Optional<Box<String>> first = stream.map(Box::of).findFirst();
(They say the solution to every OOP problem is to introduce another type :)

Optional<T> does not handle null elements

As I experimented Optional<T> does not handle null elements, so in the following example it throws a NullPointerException in the last statement:
List<String> data = Arrays.asList("Foo", null, "Bar");
data.stream().findFirst().ifPresent(System.out::println);
data.stream().skip(1).findFirst().ifPresent(System.out::println);
So, I still have to explicitly deal with null and filter non-null elements, such as:
data.stream()
.filter(item -> item != null)
.skip(1)
.findFirst()
.ifPresent(System.out::println);
Is there any alternative that avoids dealing explicitly with null as: item != null
You can use .filter(Objects::nonNull) using the method Objects.nonNull(…) added for this purpose.
There is no way to avoid explicit filtering, unless you avoid having nulls in your source list in the first place.
Note that it would be strange if the Optional handled the null in this case as it would yield an empty optional which had the semantic of “there is no first element” which implies “the stream was empty” which is just wrong.
Dealing with nulls explicitly is the cleanest solution here as it also allows you to explicitly tell whether you want .filter(Objects::nonNull).skip(1), .skip(1).filter(Objects::nonNull)…
…or .map(s->s==null? "null-replacement": s).findFirst()
It really depends on what you want to do. If you want to treat null as a valid value, the answer is different than if you want to skip nulls.
If you want to keep "nulls" in your stream:
List<String> data = Arrays.asList("Foo", null, "Bar");
data.stream().map(Optional::ofNullable).findFirst().flatMap(Function.identity()).ifPresent(System.out::println); ;
data.stream().map(Optional::ofNullable).skip(1).findFirst().flatMap(Function.identity()).ifPresent(System.out::println);
If you want to remove nulls from your stream, use data.stream().filter(Objects::nonNull) to filter it out (or as you stated o -> o != null, whatever you prefer.

Design choice: Any good reason for 'ToArray()' LINQ extension to throw an exception for null collections?

Unsurprisingly, following code will throw an ArgumentNullException
IEnumerable<string> collection = null;
string[] collectionViewAsAnArray = collection.ToArray();
This looks obvious at first sight ... but ain't incoherent to argue that returning null may have been a reasonnable alternative (Accounting that ToArray() is an extension method and therefor can be called, even on null).
While I acknowledge, this way, extension behave like a real method, I can't help finding the other approach really smart too ... but this may lead to other issues?
Granted IEnumerable is an interface used in collections but the underlying implementation is an object and you have set that collection variable to point to null, hence the exception.
If on the other hand you initialized collection with:
IEnumerable<string> collection = Enumerable.Empty<string>();
OR
IEnumerable<string> collection = new List<string>();
You would have an empty list object that you could act on. The ArgumentNullException exception is thrown because the collection argument is in fact null and that is what ToArray() is trying to act on. So logically, to me anyways, this was the only design choice.
Edit
On the other hand, in practice, I've made the conscious decision to always return a valid IEnumerable<T> when the return type on my class methods are supposed to return an IEnumerable<T>.
For example; a method signature that looks like IEnumerable<T> GetAll() would always return a valid enumerable and If there was nothing to return then I would return return Enumerable.Empty<T>();
The difference here to me is that GetAll() is not acting on a collection argument. You could really look at this like the collection is really nothing more than a parameter to the method and if you passed in a null parameter to a regular method you would probably throw an ArgumentNullException.
The short answer is that your collection variable is an expected argument (or parameter) to the ToArray() method and it is null so it makes sense to throw an ArgumentNullException.
Why push the error to some other spot in your code? If you expect that something can be null, check it before you use it. Otherwise throw an error exactly at the spot where your assumption was false, namely when you tried to convert it to an array.
I understand it can be debatable when you're chaining operations but in those cases I've found it easier to work with an empty IEnumerable rather than a null one.

Resources