SpringBoot series of tutorials JPA wrong posture of the environment configuration problem

Jpa back on the tutorial, this one stems from a simple project needs to read and write db, the thinking used directly jpa would be more simple, but sad reminder that the actual development process, we found a lot of the pit; This article is the wrong attitude of the first chapter, Repository interfaces can not be injected into the problem

<!-- more -->

I. Configuration Problems

Jpa open a new project combines springboot can easily achieve, but under certain circumstances, may experience JpaRepository custom interface can not be injected into the problem

Basic configurations

In the spring-boot environment, it is necessary pom.xmlfile, specifies the following two dependencies

<dependency>
    <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> 

Next you need to modify the configuration file ( application.properties), configuration information for the specified database

## DataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root spring.datasource.password= spring.jpa.database=MYSQL spring.jpa.hibernate.ddl-auto=none spring.jpa.show-sql=true spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 

2. Fill the failure case reproduced

First, the story mysql database, add a table

CREATE TABLE `meta_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT, `group` varchar(32) NOT NULL DEFAULT '' COMMENT '分组', `profile` varchar(32) NOT NULL DEFAULT '' COMMENT 'profile 目前用在应用环境 取值 dev/test/pro', `desc` varchar(64) NOT NULL DEFAULT '' COMMENT '解释说明', `deleted` int(4) NOT NULL DEFAULT '0' COMMENT '0表示有效 1表示无效', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), KEY `group_profile` (`group`,`profile`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='业务配置分组表'; 

Then define the table corresponding Entity

@Data
@Entity
@Table(name = "meta_group")
public class MetaGroupPO { @Id @Column(name = "`id`") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "`group`") private String group; @Column(name = "`profile`") private String profile; @Column(name = "`desc`") private String desc; @Column(name = "`deleted`") private Integer deleted; @Column(name = "`create_time`") @CreatedDate private Timestamp createTime; @Column(name = "`update_time`") @CreatedDate private Timestamp updateTime; } 

Corresponding to the interface repository

public interface GroupJPARepository extends JpaRepository<MetaGroupPO, Integer> { List<MetaGroupPO> findByProfile(String profile); MetaGroupPO findByGroupAndProfileAndDeleted(String group, String profile, Integer deleted); @Modifying @Query("update MetaGroupJpaPO m set m.desc=?2 where m.id=?1") int updateDesc(int groupId, String desc); @Modifying @Query("update MetaGroupJpaPO m set m.deleted=1 where m.id=?1") int logicDeleted(int groupId); } 

A simple data manipulation package typeGroupManager

@Component

public class GroupManager { @Autowired private GroupJPARepository groupJPARepository; public MetaGroupPO getOnlineGroup(String group, String profile) { return groupJPARepository.findByGroupAndProfileAndDeleted(group, profile, 0); } public Integer addGroup(String group, String profile, String desc) { MetaGroupPO jpa = new MetaGroupPO(); jpa.setGroup(group); jpa.setDesc(desc); jpa.setProfile(profile); jpa.setDeleted(0); Timestamp timestamp = Timestamp.from(Instant.now()); jpa.setCreateTime(timestamp); jpa.setUpdateTime(timestamp); MetaGroupPO res = groupJPARepository.save(jpa); return res.getId(); } } 

The next focus here, when we start classes, not when outside, problems may occur; the project is structured as follows

We look at the configuration classes, and classes start the application error

@Configuration
@ComponentScan("com.git.hui.boot.jpacase")
public class JpaCaseAutoConfiguration { } @SpringBootApplication public class ErrorApplication { public static void main(String[] args) { SpringApplication.run(ErrorApplication.class); } } 

Direct failed to start, an exception in the following figure, not able to find GroupJPARepositorythe bean, and the bean in normal startup mode, the spring will help us generate a proxy class; and here is obviously not generated

3. case analysis

The above case may be a bit extreme, in general, project startup class, we will be on the outermost layer; basically not there such a project structure above, the analysis of this case have wool?

A typical case

  • We will operate in a logical db Module1 (eg dao.jar) encapsulated in
  • Then there is a startup module, introduced by maven on dao.jar
  • This is the default scanning range of the entrance, it might not contain dao.jar, and therefore is likely to result in failure of implantation

4. Solution

So how to solve this problem?

在配置类中,添加两个注解EnableJpaRepositoriesEntityScan,并制定对应的包路径

@Configuration
@EnableJpaRepositories("com.git.hui.boot.jpacase")
@EntityScan("com.git.hui.boot.jpacase.entity") public class TrueJpaCaseAutoConfiguration { } 

然后再次测试

@SpringBootApplication
public class TrueApplication { public TrueApplication(GroupManager groupManager) { int groupId = groupManager.addGroup("true-group", "dev", "正确写入!!!"); System.out.println("add groupId: " + groupId); MetaGroupPO po = groupManager.getOnlineGroup("true-group", "dev"); System.out.println(po); } public static void main(String[] args) { SpringApplication.run(ErrorApplication.class); } } 

5. 小结

最后小结一下,当我们发现 jpa 方式的 Repository 无法注入时,一般是因为接口不再我们的扫描路径下,需要通过@EntityScan@EnableJpaRepositories来额外指定

来源:泉州网站优化

Guess you like

Origin www.cnblogs.com/1994july/p/12080399.html