hibernate - Spring boot + hibernate - 实体未映射 + 最佳配置方式

标签 hibernate spring-boot

我正在尝试使用 hibernate 学习 spring-boot 基本注释配置,使自己成为一个永远有效的模板。

我在 STS(spring 工具套件)3.8.3 上使用 spring-boot 最新版本 1.51。

这是我的主要内容:

@SpringBootApplication
@EnableAutoConfiguration
public class DemoApplication {

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

现在,我知道 @SpringBootApplication 自动带有 @componetScan,所以我没有添加它。

我的配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "someEntityManagerFactory", transactionManagerRef = "someTransactionManager", basePackages = {
        "com.example.*" })
@EntityScan(basePackages = "com.demo.models")
@ConfigurationProperties(prefix = "mysql.datasource")
public class DataBaseConfig {

    @Autowired
    private Environment env;

    @Bean
    public DataSource someDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("mysql.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("mysql.datasource.url"));
        dataSource.setUsername(env.getProperty("mysql.datasource.username"));
        dataSource.setPassword(env.getProperty("mysql.datasource.password"));
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean someEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(someDataSource());
        em.setPackagesToScan(new String[] { "org.openlegacy.analytics.models" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }

    @Bean
    public PlatformTransactionManager someTransactionManager() {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(someEntityManagerFactory().getObject());
        tm.setDataSource(someDataSource());
        return tm;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
        properties.setProperty("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
        properties.setProperty("spring.jpa.show-sql", env.getProperty("spring.jpa.show-sql"));
        properties.setProperty("spring.jpa.hibernate.naming.physical-strategy",
                env.getProperty("spring.jpa.hibernate.naming.physical-strategy"));
        return properties;
    }

}

我的 Controller 类:

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserRepository userRipository;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public List<User> getItems() {
        return userRipository.getUsers();
    }

    @RequestMapping(value = "/message", method = RequestMethod.GET)
    public String getMessage() {
        return userRipository.getMessage();
    }

}

我的存储库类:

@Transactional
@Repository
public class UserRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @SuppressWarnings("unchecked")
    public List<User> getUsers() {
        return entityManager.createQuery("select u from User u").getResultList();
    }

    public String getMessage() {
        return "hello";
    }
}

我的实体类:

@Entity(name = "user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "password")
    private String password;

    public Integer getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

和我的属性文件:

# DataSource settings: set here your own configurations for the database connection.
mysql.datasource.username=openlegacy
mysql.datasource.password=openlegacy
mysql.datasource.driver-class-name=com.mysql.jdbc.Driver
mysql.datasource.url=jdbc:mysql://localhost:3306/olbank
spring.jpa.database= MYSQL

spring.data.jpa.repositories.enabled=true
#spring.jpa.database-platform=org.hibernate.dialect.MYSQL5Dialect

# Show or not log for each sql query
spring.jpa.show-sql = true

# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update

# Naming strategy
#spring.jpa.hibernate.naming.strategy= org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.hibernate.naming.physical-strategy= org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

当我试图从用户表中检索数据时,出现此错误:

org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped...

我的问题是:

  1. 为什么会出现此错误?我知道用户是由类名映射的,这就是我正在做的

  2. 这是使用 spring-boot 配置 hibernate 的最佳方式吗?按照最佳实践编写代码对我来说很重要。

请详细回答,以便我学习。

欢迎提供任何其他有用的信息:)

谢谢。

最佳答案

好的。您需要在整体配置中解决一些问题。您目前正在为您的实体用户提供别名

@Entity(name = "user")

这很好,但是如果您要为您的实体提供一个名称,那么这就是您需要在 JPQL 中引用它的方式,因此,“select u from User u”需要变为

select u from user u

我可能只是建议去掉您的名称限定符并将您的查询保留为“select u from User u”。

其次,您在包引用方面确实存在一些问题:

  1. 在您的 @EnableJpaRepositories 注释中更改您的 basePackages 引用你的实际存储库包的基础,猜测 “com.demo.repository”。去掉通配符引用。
  2. 在您的 someEntityManagerFactory() 方法中,您正在设置 basePackage 到(我想是不正确的) "org.openlegacy.analytics.models". 您表示您的实体是 在 “com.demo.models” 下。因此,您应该将该 setter 更改为

    em.setPackagesToScan(new String[] { "com.demo.models" });
    

这应该可以解决问题。

关于hibernate - Spring boot + hibernate - 实体未映射 + 最佳配置方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42160915/

相关文章:

java - XML 文档结构必须在同一实体内开始和结束

xml - 初始 SessionFactory 创建失败。org.hibernate.InvalidMappingException : Unable to read XML

spring-boot - 将 Spring Boot 配置文件添加到 Sleuth/Zipkin 日志

java - 是否可以重新启动 springboot 应用程序?

java - spring-boot jackson 单个对象作为数组

java - 如何在 spring 中创建一个非阻塞的@RestController webservice?

java - 隐藏集合中的项目

java - StaleObjectStateException 或 OptimisticLockingException

mysql - 使用 Hibernate 和 MySQL,全局和本地的 Spring 事务管理

spring - 如何使用@Query在日期之间选择Spring数据MongoDB