Spring jpa+hibernate在@OneToMany关系中返回空列表

huangapple go评论65阅读模式
英文:

Spring jpa+hibernate returns empty list in @OneToMany relation

问题

I have created 2 Entity classes:

@MappedSuperclass
class BaseEntity(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    var id: Long,

    @Column(name = "created", nullable = false)
    var created: Instant,

    @Column(name = "updated", nullable = false)
    var updated: Instant
) {
}
@Entity
@Table(name = "users")
class User(
    id: Long = 0,

    @Column(name = "name", nullable = false)
    var name: String,

    @Column(name = "email", nullable = false)
    val email: String,

    created: Instant = Instant.now(),

    updated: Instant = Instant now(),

    @Enumerated(EnumType.STRING)
    var status: UserStatus = UserStatus.NOT_CONFIRMED,

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
    val auths: MutableList<UserAuth>
) : BaseEntity(id, created, updated)
@Entity
@Table(name = "auths")
class UserAuth(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    val id: Long = 0,

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    var status: UserStatus = UserStatus.ACTIVE,

    @Column(name = "auth_info")
    @JdbcTypeCode(SqlTypes.JSON)
    var auth: BaseAuth,

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    val user: User,

    created: Instant = Instant.now()
) : BaseAuth(created) {
}

When trying to get a value that has already been saved in the database (using UserRepository.findById(...)), it returns an empty list (for User.auths). I have checked that UserAuth is connected to User when trying to find.

Also, it's marked for the plugin all-open in the Gradle file:

allOpen {
	annotation("jakarta.persistence.Entity")
	annotation("jakarta.persistence.MappedSuperclass")
	annotation("jakarta.persistence.Embeddable")
}

I use Liquibase for migrations, and when I set spring.jpa.hibernate.ddl-auto: validate (it throws an exception about a schema error) - but it is configured to none (as recommended in all tutorials).

I have tried to add @Join(table="auths"), @Fetch(FetchMode.SELECT/SUBSELECT), @JoinColumn("user_id"), and it caused no result at all.

How to fix this problem?

英文:

I have created 2 Entity classes:

@MappedSuperclass
class BaseEntity(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;id&quot;, nullable = false)
    var id: Long,

    @Column(name = &quot;created&quot;, nullable = false)
    var created: Instant,

    @Column(name = &quot;updated&quot;, nullable = false)
    var updated: Instant,

    ) {
}
@Entity
@Table(name = &quot;users&quot;)
class User(
    id: Long = 0,

    @Column(name = &quot;name&quot;, nullable = false)
    var name: String,

    @Column(name = &quot;email&quot;, nullable = false)
    val email: String,

    created: Instant = Instant.now(),

    updated: Instant = Instant.now(),

    @Enumerated(EnumType.STRING)
    var status: UserStatus = UserStatus.NOT_CONFIRMED,

    @OneToMany(fetch = FetchType.EAGER, mappedBy = &quot;user&quot;)
    val auths: MutableList&lt;UserAuth&gt;
) : BaseEntity(id, created, updated)
@Entity
@Table(name = &quot;auths&quot;)
class UserAuth(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;id&quot;)
    val id: Long = 0,

    @Column(name = &quot;status&quot;)
    @Enumerated(EnumType.STRING)
    var status: UserStatus = UserStatus.ACTIVE,

    @Column(name = &quot;auth_info&quot;)
    @JdbcTypeCode(SqlTypes.JSON)
    var auth: BaseAuth,

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = &quot;user_id&quot;)
    val user: User,


    created: Instant = Instant.now()
) : BaseAuth(created) {
}

When trying to get value that already had been saved in database (by UserRepository.findById(...)) it returns empty list (at User.auths). I have checked that UserAuth is connected to User when trying to find.

Also it marked for plugin all-open in gradle file:

allOpen {
	annotation(&quot;jakarta.persistence.Entity&quot;)
	annotation(&quot;jakarta.persistence.MappedSuperclass&quot;)
	annotation(&quot;jakarta.persistence.Embeddable&quot;)
}

I use liquidbase for migrations, and when I set spring.jpa.hibernate.ddl-auto:validate (it throws exception about schema error) - but it configured to none (as recomended in all tutorials)

I have tried to add @Join(table="auths"), @Fetch(FetchMode.SELECT/SUBSELECT),@JoinColumn("user_id") and it's caused no result at all.

How to fix this problem?

答案1

得分: 0

我找到了问题的原因:Hibernate有一级缓存。如果我尝试获取刚刚保存的实体,将不会发出对数据库的请求,而是返回缓存中的实体。

英文:

I found reason of my problem: hibernate has first level cache. If I am trying to get an entity that I have just saved, the request to the database will not be made and the entity from the cache will be returned.

huangapple
  • 本文由 发表于 2023年3月4日 00:25:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定