Java 为什么@Basic(fetch=lazy)在我的情况下不起作用?

Java 为什么@Basic(fetch=lazy)在我的情况下不起作用?,java,hibernate,lazy-loading,hibernate-mapping,Java,Hibernate,Lazy Loading,Hibernate Mapping,我知道类似的问题已经被问了很多次了,但我还没有找到一个可以帮助我的 那么,我能请你帮我找出一本书的书名被急切地取出来的原因吗 我有一个非常简单的代码库,下面是我的实体: @Entity @NoArgsConstructor @AllArgsConstructor @Data @Builder public class Book { @Id @GeneratedValue private int id; @Lob @Basic(fetch = Fetch

我知道类似的问题已经被问了很多次了,但我还没有找到一个可以帮助我的

那么,我能请你帮我找出一本书的书名被急切地取出来的原因吗

我有一个非常简单的代码库,下面是我的实体:

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class Book {

    @Id
    @GeneratedValue
    private int id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;

}
下面是一段客户端代码,在本例中由psvm表示:

为了增强字节码,我还向maven添加了一个插件:

   <build>
        <plugins>
            <plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>5.3.6.Final</version>
                <executions>
                    <execution>
                        <configuration>
                            <enableLazyInitialization>true</enableLazyInitialization>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
   </build>
由于hibernate.show_sql=true,我可以看到

你能帮我找出我做错了什么吗? 答案似乎是表面上的,但我看不出来

根据JPA规范,@Basic Lazy loading不能保证应用于您正在使用的实现。你可以在这里查一下

在JPA中,对Basic上的延迟抓取的支持是可选的,因此一些JPA提供商可能不支持它

无论如何,一种解决方法是创建一个新的分离实体,例如BookTitle,然后建立一对一的关系,并从Book实体中惰性地加载它:

public class BookTitle {
    @Id
    @GeneratedValue
    private Long id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;
}


public class Book {

    @Id
    @GeneratedValue
    private int id;

    @OneToOne (fetch = FetchType.LAZY)
    private BookTitle bookTitle;

}
根据JPA规范,@Basic Lazy loading不能保证应用于您正在使用的实现。你可以在这里查一下

在JPA中,对Basic上的延迟抓取的支持是可选的,因此一些JPA提供商可能不支持它

无论如何,一种解决方法是创建一个新的分离实体,例如BookTitle,然后建立一对一的关系,并从Book实体中惰性地加载它:

public class BookTitle {
    @Id
    @GeneratedValue
    private Long id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;
}


public class Book {

    @Id
    @GeneratedValue
    private int id;

    @OneToOne (fetch = FetchType.LAZY)
    private BookTitle bookTitle;

}

如果您使用FetchType.LAZY,这会有帮助吗?链接对象不需要用@Entity注释吗?i、 你不能和字符串一起使用。将其与字符串一起使用是没有意义的,否则在本案例书中,除了检索主对象外,没有其他实际获取它的场景。可能不支持对简单类型(即原语、它们的包装器、字符串等)的延迟获取。这通常没有多大意义。为什么Hibernate不能创建实体类的代理来为包装器提供延迟加载,字符串等?在大多数情况下,延迟加载属性没有多大意义,因为您需要更多的查询来获取属性,如果您只对其中一些属性感兴趣,您可以始终使用类似“从book book中选择book.id”的查询。。。如果您使用FetchType.LAZY,链接对象不需要用@Entity注释吗?i、 你不能和字符串一起使用。将其与字符串一起使用是没有意义的,否则在本案例书中,除了检索主对象外,没有其他实际获取它的场景。可能不支持对简单类型(即原语、它们的包装器、字符串等)的延迟获取。这通常没有多大意义。为什么Hibernate不能创建实体类的代理来为包装器提供延迟加载,字符串等?在大多数情况下,延迟加载属性没有多大意义,因为您需要更多的查询来获取属性,如果您只对其中一些属性感兴趣,您可以始终使用类似“从book book中选择book.id”的查询。。。相反
 @Basic(fetch = FetchType.LAZY, optional = false)
public class BookTitle {
    @Id
    @GeneratedValue
    private Long id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;
}


public class Book {

    @Id
    @GeneratedValue
    private int id;

    @OneToOne (fetch = FetchType.LAZY)
    private BookTitle bookTitle;

}