Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Spring KafkaListener使用Hibernate一对一单向映射失败_Spring_Hibernate_Apache Kafka_Spring Data Jpa - Fatal编程技术网

Spring KafkaListener使用Hibernate一对一单向映射失败

Spring KafkaListener使用Hibernate一对一单向映射失败,spring,hibernate,apache-kafka,spring-data-jpa,Spring,Hibernate,Apache Kafka,Spring Data Jpa,我使用Spring数据JPA在Hibernate中建模了一对一关系。以下是我的模型: import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table

我使用Spring数据JPA在Hibernate中建模了一对一关系。以下是我的模型:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Nationalized;
import org.hibernate.annotations.Parameter;

@Data
@Entity
@Table(name = "parent")
public class Parent
{
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq-gen")
    @GenericGenerator(name = "seq-gen", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = { @Parameter(name = "sequence_name", value = "test_seq") })
    @Column(name = "id")
    private Long id;

    @Nationalized
    @Column(name = "Name", length = 50, nullable = false)
    private String name;
}

子表与父表具有外键关系,父表本身使用
@MapsId
映射到子表的主键。请注意,这是一种单向关系

我使用SpringDataJPA的
JpaRepository
将对象持久化到数据库中

public interface ParentRepository extends JpaRepository<Parent, Long>{}
我创建了一个RESTful控制器,它有一个自动连接的
ServiceImpl
对象,它调用服务类的适当方法

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ControllerRestful
{
    @Autowired
    private ServiceImpl service;

    @PostMapping(value = "/test")
    @ResponseStatus(HttpStatus.OK)
    public void create(@RequestBody UserDTO dto)
    {
        System.out.println(dto);
        service.create();
        System.out.println("Done");
    }
}
请注意,服务类独立于控制器。我在本地测试了这个端点,它将父对象和子对象持久化到数据库中

public interface ParentRepository extends JpaRepository<Parent, Long>{}
现在,当我切换到基于卡夫卡的控制器时,它在持久化时抛出一个错误

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class ControllerKafka
{
    @Autowired
    private ServiceImpl service;

    @KafkaListener(topics = "..", groupId = "..")
    @SendTo
    public void create(UserDTO dto, Acknowledgment acknowledgment)
    {
        service.create();
        System.out.println("Done");
        acknowledgment.acknowledge();
    }
}
错误日志:

org.springframework.kafka.listener.ListenerExecutionFailedException: Listener method 'public void ControllerKafka.create(UserDTO,org.springframework.kafka.support.Acknowledgment)' threw exception; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: models.Parent;
nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: models.Parent; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: models.Parent; 
nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: models.Parent
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.decorateException(KafkaMessageListenerContainer.java:1899) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeErrorHandler(KafkaMessageListenerContainer.java:1887) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:1792) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:1719) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:1617) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:1348) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1064) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:972) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

ControllerKafka
而不是
ControllerRestful
的情况下,在
serviceinpl
中持久化
Child
对象怎么可能失败?另外,如果我从
子实体中删除
@MapsId
属性,并且对
子实体具有不同的主键和外键,则在持久化时不会出现错误。

创建()
方法上使用
@Transactional
,删除
@MapsId
@zlaval如果我删除
@MapsId
是否有更好的方法来建模主键=外键的实体?使用
@Transactional
它工作正常,我不确定这是如何发生的。没有
@Transactional
,如果我在
childRepository.save(child)
中添加调试检查点并检查数据库,Hibernate已经持久化了
父对象
对象,然后当我从检查点恢复并持久化
子对象时,它失败了。(另外,如果我在从检查点恢复之前突然关闭程序,它不会回滚)。另外,为什么使用
@RestController
,不需要添加
@Transactional
?使用onetoone,子对象的fk将是父对象pk。如果不使用Transactional,则两个保存方法将获得不同的EntityManager。因此,在第一次保存后,保存的实体将被弃用。请在
create()上使用
@Transactional
方法,并删除
@MapsId
@zlaval如果我删除
@MapsId
是否有更好的方法对主键=外键的实体建模?使用
@Transactional
它工作正常,我不确定这是如何发生的。如果没有
@Transactional
,如果我在
childRepository.save(child)添加调试检查点
我检查了数据库,Hibernate已经保存了
父对象
对象,然后当我从检查点恢复并保存
子对象时,它失败了。(另外,如果我在从检查点恢复前突然关闭程序,它不会回滚)。另外,为什么使用
@RestController
,不需要添加
@Transactional
?使用onetoone,子对象的fk将是父对象pk。如果不使用Transactional,则两个保存方法将获得不同的EntityManager。因此,在第一次保存后,保存的实体将被弃用。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class ControllerKafka
{
    @Autowired
    private ServiceImpl service;

    @KafkaListener(topics = "..", groupId = "..")
    @SendTo
    public void create(UserDTO dto, Acknowledgment acknowledgment)
    {
        service.create();
        System.out.println("Done");
        acknowledgment.acknowledge();
    }
}
org.springframework.kafka.listener.ListenerExecutionFailedException: Listener method 'public void ControllerKafka.create(UserDTO,org.springframework.kafka.support.Acknowledgment)' threw exception; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: models.Parent;
nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: models.Parent; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: models.Parent; 
nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: models.Parent
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.decorateException(KafkaMessageListenerContainer.java:1899) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeErrorHandler(KafkaMessageListenerContainer.java:1887) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:1792) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:1719) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:1617) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:1348) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1064) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:972) ~[spring-kafka-2.5.2.RELEASE.jar:2.5.2.RELEASE]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]