运行时生成的存储库和实体

时间:2017-10-29 11:22:02

标签: spring spring-boot dependency-injection spring-data-jpa javapoet

在我的SpringBoot应用程序中,我使用javapoet生成hibernate实体类和存储库,而不是在运行时使用OpenHFT分别编译这些生成的源文件。 My目的是能够持久存储这些运行时生成的实体。

我可以在我的rest控制器中成功使用这个生成的实体,并将@RequestBody json String映射到这个实体。 但我的问题是我无法将运行时生成的存储库注入控制器..

以下是运行时生成的实例示例;

@Entity
public class Author extends BaseEntity{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;

    public Author(){
        super();
    }

    public Long getId() {
        return id;
    }

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

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

以下是上面实体

的运行时生成存储库
import org.springframework.stereotype.Repository;
import java.lang.Long;
import com.mrg.domain.Author;

@Repository("authorRepository")
public interface AuthorRepository extends GenericRepository<Author, Long> {

}

这是我使用的通用存储库,以便我可以在运行时注入我的存储库

@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable  > extends PagingAndSortingRepository<T, ID>{

}

下面是我的休息控制器。这里我将通用存储库自动装配为Map,以便Spring在使用存储库名称作为键时动态注入正确的存储库实现;

  

genericRepo.get(repoName).save(模型);

@RestController
@RequestMapping("/{entity}")
public class GenericRestController {


    @Autowired
    private Map<String, GenericRepository> genericRepo;

    @RequestMapping(value = "/{entity}/", method = RequestMethod.POST)
    public @ResponseBody Object createEntity(@PathVariable String entity, @RequestBody String requestBody) {

        Object model = null;
        ObjectMapper mapper = new ObjectMapper();
        String repoName = "";

        try {

            // ex : if {entitiy} param is equal "author" modelName will be "Post"
            String modelName = Character.toUpperCase(entity.charAt(0)) + entity.substring(1);

            Class<?> clazz = Class.forName("com.mrg.domain." + modelName);
            model = clazz.newInstance();

            // Converting @RequestBody json String to domain object..
            model = mapper.readValue(requestBody, clazz);

            // Repository name is {entity} + "Repository" ex : authorRepository
            repoName = entity.concat("Repository");

        } catch (Exception ex) {

            // handling exceptions..
        }
        // Saving with right repository 
        return genericRepo.get(repoName).save(model);
    }
}

这适用于我手动编写的存储库,我可以动态地使用这种方法持久化对象。但我无法访问我的运行时生成的存储库。(genericRepo.get(&#34; authorRepository&#34;)返回空引用)

你能为这个问题建议一个解决方案吗?我在这里失踪了什么?持久化运行时生成的对象的任何其他想法都会有所帮助。

谢谢..

2 个答案:

答案 0 :(得分:0)

您的存储库位于一个包中,例如com.mypackage.repository。在您的配置中,您应该扫描此包(以及包含控制器的包),以便Spring知道这些bean:

@Configuration
@ComponentScan(value = {"com.mypackage.controller"})
@EnableJpaRepositories(basePackages = {"com.mypackage.repository"})
public class MyConfig {
    // creation and configuration of other beans
}

Config类可能有更多注释用于您自己的目的(例如,@ EnableTransactionManagement,@ PropertyTource用于文本文件中的道具)。我只是发布了一套强制性的注释。

答案 1 :(得分:0)

最近,我遇到了类似的情况,必须在运行时生成存储库以减少样板代码。通过一些研究,结果发现,在扫描带有@Repository注释的接口时,它使用的是ClassPathScanningCandidateComponentProvider,它扫描类路径中的类,而忽略运行时生成的类。

相关问题