【问题标题】:Why does my Entity does not work with SpringBoot although it works without为什么我的实体无法与 SpringBoot 一起使用,尽管它可以在没有 SpringBoot 的情况下使用
【发布时间】:2019-03-19 16:43:39
【问题描述】:

(请注意:在对 this issue 进行调查时,我更好地发现了我在这里介绍的问题根源)

我对 Hibernate 和 SpringBoot 很陌生。我的项目处理一个搜索引擎,它的索引(javafx 客户端)和搜索(Web 客户端)部分是分开的。 Web 客户端使用 SpringBoot,在用户请求的过程中,我需要检索 Solr 索引上的信息以进行搜索。这些信息存储在 Hibernate / H2 本地数据库中,我使用以下实体类:

@Entity
@Table(name = "IndexSetups")
@Access(AccessType.PROPERTY)
public class IndexSetup {
 private final SimpleIntegerProperty id = new SimpleIntegerProperty();

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO) // For H2 AUTO is required to auto increment the id
 public int getId() {
  return id.get();
}

 //... other properties, getters and setters

}

LocalDatabase 类具有列出数据库中所有 IndexSetup 的方法(还有其他方法,但关注这一方法足以理解问题)。我需要在控制器中调用它,但我得到了 "Not an entity : class IndexSetup"

但是,使用我的实体的唯一方法是阻止 SpringBoot 的启动(即注释以 SpingApplication.run(...) 开头的行):

@SpringBootApplication
public class ServerApplication {

public static void main(String[] args) {
//      SpringApplication.run(ServerApplication.class, args); 

ArrayList<IndexSetup> availableSearchIndex = 
LocalDatabase.getInstance(false) // no GUI
            .getAllIndexSetups();

// The list is displayed as long as SpringApplication.run() call is commented. Otherwise "Not an entity"
System.err.println("The Index setups are " + availableSearchIndex); 
  }
}

当然这不是一个解决方案,因为我确实需要通过 Spring Boot 处理用户的请求:-D!

最后是 hibernate.cfg.xml 文件:

<hibernate-configuration>
  <session-factory>      
    <!-- Database connection settings -->
    <property name="connection.driver_class">org.h2.Driver</property>
    <!--The db file resides wihtin the parent project (so one level above the calling project see ../)-->
    <!--We use the auto server mode to be able to open the database from server and from indexer simultaneously
    see http://www.h2database.com/html/features.html#auto_mixed_mode -->
    <property name="connection.url">jdbc:h2:file:../MyAppDB;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE</property>
    <property name="connection.username">test</property>
    <property name="connection.password"/>
    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>
    <!-- SQL dialect -->
    <property name="dialect">org.hibernate.dialect.H2Dialect</property>
    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">false</property>
    <!-- Updates the existing database schema on startup -->
    <property name="hbm2ddl.auto">update</property>
    <!-- The mapping information of entities -->
    <mapping class="my.package.Entities.IndexSetup"/>
 </session-factory>
</hibernate-configuration>

堆栈跟踪是:

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

Caused by: java.lang.IllegalArgumentException: Not an entity: class my.package.Entities.IndexSetup
at org.hibernate.metamodel.internal.MetamodelImpl.entity(MetamodelImpl.java:457)
at org.hibernate.query.criteria.internal.QueryStructure.from(QueryStructure.java:126)
at org.hibernate.query.criteria.internal.CriteriaQueryImpl.from(CriteriaQueryImpl.java:153)
at my.package.LocalDatabase.getAllIndexSetups(LocalDatabase.java:99)
at my.package.ServerApplication.main(ServerApplication.java:15)

我刚刚注意到 Spring Boot 在启动时打印的那两行:

2018-10-15 11:47:46.208  INFO 27730 --- [  restartedMain] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found // Maybe this one is not just "INFO"
2018-10-15 11:47:46.591  WARN 27730 --- [  restartedMain] org.hibernate.orm.connections.pooling    : HHH10001002: Using Hibernate built-in connection pool (not for production use!)
2018-10-15 11:47:46.594  INFO 27730 --- [  restartedMain] org.hibernate.orm.connections.pooling    : HHH10001005: using driver [org.h2.Driver] at URL [jdbc:h2:file:../MyAppDB;DB_CLOSE_ON_EXIT=TRUE;FILE_LOCK=NO] // Just to show that my bibernate.cfg.xml is found

看起来不太可能是依赖问题,因为它仅在 Spring 应用程序运行时停止工作。

所以我的问题是:我应该怎么做才能让我的实体在 SpringBoot 中工作?

非常感谢任何帮助!

【问题讨论】:

  • 能否将错误堆栈跟踪作为代码提供给我们?
  • @Christian 看到我的编辑。
  • 你的代码没有使用 Spring boot。至少主要方法不是启动任何与启动相关的东西。从您使用普通休眠和休眠来配置它的事实来看,您似乎也在尝试解决 Spring Boot。所有这些都可以通过 Spring Boot 完成。此外,您希望您的 ServerApplication 位于顶级包中,以便可以检测到每个功能(如 Spring Boot 团队所建议的那样)。这也显示在您链接的其他问题中。
  • 感谢@M.Deinum,但在数据库中存储 IndexSetups 的索引客户端需要hibernate.cfg.xml。最后,用户必须能够独立于服务器启动索引器,反之亦然。您能否建议一种架构,也许我用父 pom.xml 设计的架构不合适?顺便说一句,当索引器和服务器在同一个项目中时,它曾经工作过。
  • @M.Deinum 根据您的评论以及许多其他来源,我最终让它工作了!我将在linked question 中写下我的解决方案。基本上我删除了hibernate.cfg.xml 创建了一个 jpa 存储库,解释了here 并解决了一个接一个出现的每一个问题!

标签: java hibernate spring-boot h2


【解决方案1】:

将@EntityScan 添加到 ServerApplication.class。

@EntityScan (org.springframework.boot.autoconfigure.domain.EntityScan) 标识特定持久性上下文应该使用哪些类。

【讨论】:

  • 谢谢@martinywwan 我已经试过in the related question 没有运气。
  • 实际上这是解决方案的一部分,所以我将您的标记为已接受。然而,对于记录,即使您只有一个实体放置在 Entities 子文件夹中(像我一样),您也必须向 @EntityScan 提供仅到该子文件夹而不是实体的路径。所以@EntityScan("my.package.Entities") 有效,而@EntityScan("my.package.Entities.IndexSetups") 无效。
猜你喜欢
  • 2013-05-15
  • 2018-08-18
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 2022-12-22
相关资源
最近更新 更多