4

I have the following relationship:

@Entity
public class SomeEntity {
    //...

    @EmbeddedId
    private SomeEntityIdentity id;

    @OneToOne
    @NotFound(action = NotFoundAction.EXCEPTION) //This is the important bit
    @JoinColumns({
        //...
    })
    private OtherEntity example;

    //...
}

Then, I use Spring data's findOne() to grab my entity by the Id:

SomeEntityIdentity id = new SomeEntityIdentity();
id.setAttribute1(1);
id.setAttribute2(new BigDecimal(123));
return this.someEntityRepository.findOne(id);

The problem is that no exception is thrown if OtherEntity is not found, as findOne() simply returns null. Even if I set @OneToOne(optional = false) I still get a null from findOne(), when I was excepting only OtherEntity to be null.

I believe an exception should be thrown. Does anyone any have ideas?

Thank you!


Edit: Identity and Repository classes below.

@Embeddable
public class SomeEntityIdentity implements Serializable {
    private int attribute1;
    private BigDecimal attribute2;

    public void setAttribute1(int attribute1) {
        this.attribute1 = attribute1;
    }

    public void setAttribute2(BigDecimal attribute2) {
        this.attribute2 = attribute2;
    }
}

public interface SomeEntityRepository extends JpaRepository<SomeEntity, SomeEntityIdentity> {
}
Telmo Marques
  • 5,066
  • 1
  • 24
  • 34
  • Hmm, isn't it working correcly, then? When `findOne()` doesn't return a `SomeEntity` instance, the `@NotFound` annotation is never being processed, anyway. I have to say that I've never used that construct, but that's how I would comprehend your case. – Jan B. Jul 16 '18 at 17:18
  • Are you sure the entity with the given identifier exists? Please post `SomeEntityIdentity`. `@EmbeddedId` suggests the id is composed of more than one property, yet you're only setting one property on `id` before calling `findOne` – crizzis Jul 16 '18 at 19:02
  • @Matt, `SomeEntity` exists in the database, I've grabbed the SQL from hibernate debug logs and confirmed that a record is returned. The entity that does not exist in the database is `OtherEntity`. – Telmo Marques Jul 17 '18 at 08:25
  • @crizzis, regarding the identity it was just an example as I can't expose the actual field names. I've updated my question to reflect the actual code I have, with just names changed. I'm 100% positive that the `SomeEntity` record exists, hibernate is doing a left outer join and the query returns a result if I execute it in an SQL client. – Telmo Marques Jul 17 '18 at 08:36
  • Does fetching `SomeEntity` work when `OtherEntity` exists? Just a wild shot, but could `BigDecimal` be at fault here? Is it possible to use `BigInteger` (or `Long`) for your use case instead? My guess is that `new BigDecimal(123)` is not *really* equal to the db value for some reason – crizzis Jul 23 '18 at 11:39
  • Try to use `getOne()` instead of `findOne()`. Probably the problem is that `findOne()` returns `Optional.empty()` – Andrew Nepogoda Jul 24 '18 at 14:16
  • Exception will be thrown only when an otherEntity is not found on a association. – Jibin TJ Jul 24 '18 at 14:36
  • Thanks to everyone that contributed! It ended up being incompatible versions between Spring and Hibernate. – Telmo Marques Jul 24 '18 at 20:35

1 Answers1

1

Turned out to be an incompatibility between Hibernate and Spring Data versions.

This project was using Hibernate 4.3.1.Final to take advantage of JPA 2.1 features; but with spring-data-jpa 1.6.6.RELEASE, that doesn't support that Hibernate version.

Because everything was working correctly (up until this issue) I didn't notice this at first. When I tried upgrading spring-data-jpa to an Hibernate 4.3 compatible version I couldn't, because spring-data-jpa jumps from Hibernate 3 to Hibernate 5 on 2.0.x versions. This also seems to require Java 8, so that was a no go for me.

Ended up downgrading to Hibernate 3.6.10.Final and everything started working OK.

TL;DR: Always check version compatibility between Spring and other libraries, even if there's no obvious errors.

I just wanted to finish by saying that Spring version management is a total pain.


Working dependency configuration:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>3.6.10.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.6.10.Final</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>1.6.6.RELEASE</version>
</dependency>
Telmo Marques
  • 5,066
  • 1
  • 24
  • 34
  • I'm getting the same error on hibernate '5.4.12.Final'. I've tried downgrading to '3.6.10.Final' like you have but now instead it always throws an exception, regardless of the value I provide for @NotFound – andrei Apr 05 '20 at 16:45