There is nothing wrong with null pointers in principle.
What's wrong with older languages is that there is no way to know whether a pointer could be null or not. So you have to check whether it's null, even though according to your code it never can be null. Wasting code and time. Of course the one time where you don't check it's Null. The other extreme is when data can be present or absent and you have a language that doesn't allow a pointer to be non-null. Then you have to produce a pointer with fake data if the data is absent, just as bad.
Newer languages have "optional" values. In Swift, for every type T there is a type optional<T>. So your TEntity CANNOT be null. But an optional<TEntity> can be null. Normal code doesn't allow you to try to access the data in an optional<TEntity>. There is a special "if" that lets you try to extract the TEntity, while at the same time reporting success or failure, and if extracting the TEntity failed, then it is not accessible.
The language doesn't allow unnecessary tests - if you have a variable of type TEntity it CANNOT be null, and the compiler doesn't allow you to test if it is null. If it is of type optional<TEntity> then you MUST test if it is null in some way. So you get 100% safety, And you can very easily report that some value isn't present.
if let result = something.get(guid: someGuid) {
// result is a valid TEntity
} else {
// There is no TEntity, and no variable "result"
}