Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对Spring数据使用多个集合_Java_Spring_Hibernate_Spring Mvc_Jpa - Fatal编程技术网

Java 如何对Spring数据使用多个集合

Java 如何对Spring数据使用多个集合,java,spring,hibernate,spring-mvc,jpa,Java,Spring,Hibernate,Spring Mvc,Jpa,我真的很困惑如何在我的应用程序中使用@manytomy子集合。为了证明我的问题,我在 主要问题是,在保存父对象时,子集合被删除。我能想到的避免这种情况的唯一方法是从数据库中获取所有子集合,并在保存之前将它们附加到父对象,但我不相信这是正确的方法。所以我猜我做错了什么,希望有人能指出这一点,提高我对JPA工作原理的理解 我想在前面提到这个问题与我的相关,但我认为最好集中在问题的核心,删除所有上下文,并使用一个干净的示例项目。我希望这不是问题 父对象类Test @Entity public fina

我真的很困惑如何在我的应用程序中使用
@manytomy
子集合。为了证明我的问题,我在

主要问题是,在保存父对象时,子集合被删除。我能想到的避免这种情况的唯一方法是从数据库中获取所有子集合,并在保存之前将它们附加到父对象,但我不相信这是正确的方法。所以我猜我做错了什么,希望有人能指出这一点,提高我对JPA工作原理的理解

我想在前面提到这个问题与我的相关,但我认为最好集中在问题的核心,删除所有上下文,并使用一个干净的示例项目。我希望这不是问题

父对象类
Test

@Entity
public final class Test implements Identifiable<Integer> {

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

    @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    @JoinTable(name = "test_label", joinColumns = { @JoinColumn(name = "test") }, inverseJoinColumns = { @JoinColumn(name = "label") })
    private Set<Label> labels = new HashSet<Label>();

    private volatile String name = "";

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Test test = (Test) o;
        if (!id.equals(test.id)) return false;
        return true;
    }

    @Override
    public int hashCode() {
        if (id == null) return 0;
        return id.hashCode();
    }

}
服务
TestServiceImpl

@Service
final class TestServiceImpl implements TestService {

    private final TestRepository testRepository;

    @Autowired
    TestServiceImpl(TestRepository testRepository) {
        this.testRepository = testRepository;
    }

    @Override
    public List<Test> findAll() {
        return testRepository.findAll();
    }

    @Override
    @Transactional
    public Test save(Test test) {
        return testRepository.save(test);
    }

    @Override
    @Transactional
    public Test saveAndAdd(Test test, Label label) {
        test = testRepository.save(test);
        test.getLabels().add(label);
        return testRepository.save(test);
    }

    @Override
    @Transactional
    public Test create() {
        return testRepository.save(new Test());
    }

    @Override
    public Test findOne(Integer id) {
        return testRepository.findOne(id);
    }

}
控制器
TestConroller

@Controller
@RequestMapping("/")
public class TestController {

    private TestService testService;
    private LabelService labelService;

    private static final Logger logger = Logger.getLogger(TestController.class);

    @Autowired
    TestController(TestService testService, LabelService labelService) {
        this.testService = testService;
        this.labelService = labelService;

        // populate labels
        List<Label> labels = labelService.findAll();
        if (labels == null || labels.size() == 0) {
            labelService.create("label a");
            labelService.create("label b");
        }

    }

    @ModelAttribute("labels")
    public List<Label> getLabels() {
        return labelService.findAll();
    }

    @ModelAttribute("user")
    public String getUser() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        String name = auth.getName();
        return name;
    }

    @RequestMapping(value="/", method = RequestMethod.GET)
    public String firstPage(ModelMap model) {
        List<Test> tests = testService.findAll();
        model.addAttribute("tests", tests);
        return "index";
    }

    @RequestMapping(value="/login", method = RequestMethod.GET)
    public String login(ModelMap model) {
        return "login";
    }

    @RequestMapping(value="/addtest", method = RequestMethod.GET)
    public String addExpert(ModelMap model) {
        testService.create();
        return "redirect:/";
    }

    @RequestMapping(value="/test/{testId}", method=RequestMethod.GET)
    public String editProject(@PathVariable Integer testId, ModelMap model) {
        TestForm form = new TestForm();
        Test test = testService.findOne(testId);
        form.setTest(test);
        model.addAttribute("testForm", form);
        return "test";
    }

    @RequestMapping(value="/test", method=RequestMethod.POST)
    public String submitTest(@ModelAttribute("testForm") TestForm testForm, BindingResult result) {
        logger.info("labels: " + testForm.getTest().getLabels());
        if (testForm.getTest().getLabels() != null) {
            logger.info("labels size: " + testForm.getTest().getLabels().size());
        }
        testService.save(testForm.getTest());
        return "redirect:/";
    }

    @RequestMapping(value="/addlabel", method=RequestMethod.POST)
    public String addLabel(@ModelAttribute("testForm") TestForm testForm, BindingResult result, ModelMap model) {
        Test test = testForm.getTest();
        Label label = testForm.getLabel();
        test = testService.saveAndAdd(test, label);
        return "redirect:/test/" + test.getId();
    }
}
应用程序上下文
ApplicationContext

@Configuration
@EnableWebMvc
@ComponentScan
@Import({ SecurityConfig.class })
@PropertySource("classpath:application.properties")
@EnableJpaRepositories("test.model")
public class ApplicationContext extends WebMvcConfigurerAdapter {

    @Autowired
    public StringToLabel stringToLabel;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/resources/css/**");
        registry.addResourceHandler("/js/**").addResourceLocations("/resources/js/**");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(stringToLabel);
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource datasource = new DriverManagerDataSource();
        datasource.setDriverClassName("org.hsqldb.jdbcDriver");
        datasource.setUrl("jdbc:hsqldb:mem:test");
        datasource.setUsername("sa");
        datasource.setPassword("");
        return datasource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
        LocalContainerEntityManagerFactoryBean factoryBean
                = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource( dataSource() );
        factoryBean.setPackagesToScan( new String[ ] { "test.model" } );
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        factoryBean.setJpaVendorAdapter( vendorAdapter );
        factoryBean.setJpaProperties( this.additionalProperties() );
        return factoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                this.entityManagerFactory().getObject() );
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        return properties;
    }

}
应用程序初始值设定项
ApplicationInitializer

public class ApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationContext.class);
        rootContext.setDisplayName("Test application");

        servletContext.addListener(new ContextLoaderListener(rootContext));

        ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        FilterRegistration.Dynamic filter = servletContext.addFilter("openEntityManagerInViewFilter", OpenEntityManagerInViewFilter.class);
        filter.setInitParameter("singleSession", "true");
        filter.addMappingForServletNames(null, true, "dispatcher");

    }

}
编辑1:显然我无法初始化服务中的任何集合(调用
size()
无效)。这是否意味着父对象被分离?这也适用于
OneToMany
集合,但是我可以通过保存子集合而不是父集合来添加几个子集合


我猜我的配置一定有问题,我能做些什么吗?

看起来你在懒洋洋地加载@
manytomy
集合,然后将旧的分离对象与空的子对象(因为子对象从未加载)合并到新会话中并保存父对象。 当保存父级时,您也将相同的操作层叠到子级,这将导致与hibernate/jpa一样的删除,假设您手动删除它们并合并父级


为了避免这种情况,要么急切地加载关系中的所有子项,要么不要独立于父项级联合并和管理子项。

hi,使用(cascade=CascadeType.all)并让我知道效果。多对多和任何其他类型的关系都来自Hibernate/JPA,而不是来自Spring。Karibasapa G C,恐怕没有效果。Luiggi Mendoza,我使用的是Spring数据JPA,在调用Spring控制器后初始化惰性集合时遇到问题,可能是由于错误使用Spring事务管理或Spring上下文。所以我不明白为什么我不能提到我正在使用Spring这个事实。为了独立管理孩子们,仅仅删除cascade就足够了吗?我尝试了
@ManyToMany(fetch=FetchType.LAZY)
,但当我保存父项时,集合仍然被删除。请尝试此操作以使集合仅为只读@ManyToMany(fetch=FetchType.LAZY)@JoinTable(name=“test_label”,joinColumns={@JoinColumn(name=“test”,insertable=false,updateable=false)},inverseJoinColumns={@JoinColumn(name=“label”,insertable=false,updateable=false)})私有集标签=new HashSet();
@Configuration
@EnableWebMvc
@ComponentScan
@Import({ SecurityConfig.class })
@PropertySource("classpath:application.properties")
@EnableJpaRepositories("test.model")
public class ApplicationContext extends WebMvcConfigurerAdapter {

    @Autowired
    public StringToLabel stringToLabel;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/resources/css/**");
        registry.addResourceHandler("/js/**").addResourceLocations("/resources/js/**");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(stringToLabel);
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource datasource = new DriverManagerDataSource();
        datasource.setDriverClassName("org.hsqldb.jdbcDriver");
        datasource.setUrl("jdbc:hsqldb:mem:test");
        datasource.setUsername("sa");
        datasource.setPassword("");
        return datasource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
        LocalContainerEntityManagerFactoryBean factoryBean
                = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource( dataSource() );
        factoryBean.setPackagesToScan( new String[ ] { "test.model" } );
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        factoryBean.setJpaVendorAdapter( vendorAdapter );
        factoryBean.setJpaProperties( this.additionalProperties() );
        return factoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                this.entityManagerFactory().getObject() );
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        return properties;
    }

}
public class ApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationContext.class);
        rootContext.setDisplayName("Test application");

        servletContext.addListener(new ContextLoaderListener(rootContext));

        ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        FilterRegistration.Dynamic filter = servletContext.addFilter("openEntityManagerInViewFilter", OpenEntityManagerInViewFilter.class);
        filter.setInitParameter("singleSession", "true");
        filter.addMappingForServletNames(null, true, "dispatcher");

    }

}