Spring boot + hibernate - 实体未映射+配置

时间:2017-02-10 13:46:19

标签: hibernate spring-boot

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

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

这是我的主要内容:

@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;
    }

}

我的控制器类:

@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:用户未映射...

我的问题是:

  1. 为什么我收到此错误?我知道用户是按类名映射的,这就是我正在做的事情

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

  3. 请详细解答,以便我可以从中学习。

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

    感谢。

5 个答案:

答案 0 :(得分:8)

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

@Entity(name = "user")

这很好但是如果你要为你的实体提供一个名字,那么你需要在JPQL中引用它,所以&#34;从用户u&#34;中选择你。需要成为

select u from user u

我可能只是建议删除您的姓名限定符,并将您的查询保留为&#34;从用户u&#34;中选择您。

其次,您确实遇到了包引用的一些问题: 1)在@EnableJpaRepositories注释中,更改basePackages以引用实际存储库包的基础,猜测&#34; com.demo.repository&#34;。摆脱通配符引用。 2)在someEntityManagerFactory()方法中,您将basePackage设置为(我想象的是不正确的)&#34; org.openlegacy.analytics.models&#34;。您表示您的实体位于&#34; com.demo.models&#34;之下。所以你应该把那个setter改成

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

这应该可以解决问题。

答案 1 :(得分:1)

Spring JPA区分大小写,因此请确保您输入了正确的包URL和正确的类名。

答案 2 :(得分:1)

就我而言,我必须为实体添加名称。 @Entity(name = "users")

@Entity(name = "users")
@Table(name = "users")
public class User  implements Serializable{
}

更新 如果你让实体没有名字并写下类名,它也应该可以工作。

@Entity
@Table
public class User  implements Serializable{
}

然后

@query("select u from User u")

答案 3 :(得分:0)

实体未映射(JPA本机查询)

默认情况下,使用Spring boot JPA,每个查询将引用列或映射到数据库中每个列的@Entity类中定义的变量。

但是,可以使用本机查询或原始查询

public interface UserInfoRepository extends CrudRepository<UserModel, String>
    @Query("SELECT ID, NAME FROM USER", nativeQuery = true)
    Optional<List<UserModel>> findSomething();
}

列ID和名称是根据数据库的列名称(本机查询)

使用EntityManager

的示例
Query query = em.createNativeQuery("SELECT ID, NAME FROM USER")

我对最佳配置方式(Oracle)的建议

  1. application.yml中配置数据源
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    username: username
    password: pass
    hikari:
      idle-timeout: 1000 
      maximum-pool-size: 10
      minimum-idle: 2
      pool-name: pool-name
      jdbc-url: jdbc:oracle:thin:@localhost:1521:INSTANCE
      driver-class-name: oracle.jdbc.OracleDriver
  1. 使用@Entity或不使用lombok创建lombok类(手动创建getter,setter函数)
@Data
@NoArgsConstructor
@EntityScan
@Entity(name = "USER")
public class UserInfoModel {

    @Id
    @Column(name = "USERID")
    private long userId;
    @Column(name = "NAME")
    private String name;
    @Column(name = "DEPT")
    private String dept;
}
  1. 创建接口CRUD存储库
public interface UserInfoRepository extends CrudRepository<UserInfoModel, Long> {
}
  1. 创建一个@Service类以将存储库包装为业务层,并在此处进行逻辑设计
@Service
public class UserServiceImpl implements UserService {

   @Autowired
   private UserInfoRepository userInfoRepo;

   @Override
   public List<UserInfoModel> getUserInfo(long userId) throws Exception {
       Optional<List<UserInfoModel>> info = userInfoRepo.findById(userId);
       if (!info.isEmpty() && info.get().size() > 0) {
           return info.get();
       }
       return null;
   }
}

  1. 最后,在您的控制器中调用@Service

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

    @Autowired
    private UserService userService;
}

希望,这可以指导几周前像我一样遇到麻烦的人

答案 4 :(得分:0)

您是否尝试过以下实体

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