micronaut-projects / micronaut-sql

Projects to support SQL Database access in Micronaut
Apache License 2.0
72 stars 42 forks source link

Micronaut SQL JPA requires Micronaut Data Model dependency #1157

Open sdelamo opened 10 months ago

sdelamo commented 10 months ago

I expected the following dependencies to be enough:

    implementation("io.micronaut.data:micronaut-data-tx-hibernate")
    implementation("io.micronaut.sql:micronaut-hibernate-jpa")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    runtimeOnly("com.h2database:h2")

but without:

    implementation("io.micronaut.data:micronaut-data-model")

We don't mention in the docs micronaut-data-model is necessary.

Without it, I get:

Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.NoClassDefFoundError: io/micronaut/data/annotation/GeneratedValue$Type [in thread "Test worker"]

This is the domain of the sample app:

package example.micronaut.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;

import io.micronaut.serde.annotation.Serdeable;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Set;

import static jakarta.persistence.GenerationType.AUTO;

@Serdeable
@Entity
@Table(name = "genre")
public class Genre {

    @Id
    @GeneratedValue(strategy = AUTO)
    private Long id;

    @NotNull
    @Column(name = "name", nullable = false, unique = true)
    private String name;

    @JsonIgnore
    @OneToMany(mappedBy = "genre")
    private Set<Book> books = new HashSet<>();

    public Genre() {}

    public Genre(@NotNull String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Book> getBooks() {
        return books;
    }

    public void setBooks(Set<Book> books) {
        this.books = books;
    }

    @Override
    public String toString() {
        return "Genre{" +
            "id=" + id +
            ", name='" + name + '\'' +
            '}';
    }
}

Steps to reproduce:

clone https://github.com/grails-core-issues-forks/micronaut-sql-1157

cd ../micronaut-jpa-hibernate-gradle-java
./gradlew test
sdelamo commented 10 months ago

@dstepanov do you know what could be going on?

radovanradic commented 8 months ago

Don't know how and when this started to happen, but for some reason generated introspection classes for Genre and Book contain imports

import io.micronaut.data.annotation.GeneratedValue.Type;
import io.micronaut.data.annotation.Relation.Kind;
import io.micronaut.data.model.DataType;

and introspection is used when building session factory so that is when exception is thrown. Feels like io.micronaut.data.model.* imports shouldn't be here because Genre and Book have jakarta annotations but don't know why are these being used as micronaut-data-processor (ie annotation mapper) is not supposed be used here but maybe @dstepanov knows what is going on here.

dstepanov commented 8 months ago

When did it appear? I think we always remapped to our annotations.

This might be improved by not generating the enum reference but a simple string.

radovanradic commented 8 months ago

I didn't realize first that data-processor is added as dependency through gradle (and in maven it's not added) so that is doing mapping and adding dependencies for data-model in the generated introspections. Tried this in 3.x and gives the same error, so not sure what and when changed that we now need to add data-model explicitly.