org.springframework.orm.jpa.JpaSystemException:无法通过反射设置字段值 [POST_INSERT_INDICATOR] 值

Posted

技术标签:

【中文标题】org.springframework.orm.jpa.JpaSystemException:无法通过反射设置字段值 [POST_INSERT_INDICATOR] 值【英文标题】:org.springframework.orm.jpa.JpaSystemException: Could not set field value [POST_INSERT_INDICATOR] value by reflection 【发布时间】:2017-10-14 03:38:20 【问题描述】:

我使用 Spring Boot 项目,我有以下实体,

@Entity
public class Ip 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "IP_ADDR_ID_2")
    private Long id;

    @Column(name = "IP_ADDRESS_2")
    @NotEmpty
    private String address;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "ip")
    private List<IMAssociation> httpInfoMessages2;


下面提供消息实体,

@Entity
public class Message 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "S_ID_2")
    private Long sId;

    @Column(name = "STATUS_ID_2")
    private Long statusId;

    @NotEmpty
    @Column(name = "STATUS_2")
    private String status;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "message")
    private List<IMAssociation> message;

最后,实体提供了IP和消息之间的关联,

@Entity
@Table(name = "IP_HTTP_MESSAGE")
//@IdClass(AssociationId.class)
public class IMAssociation implements Serializable

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

    @Id
    @Column(name = "IP_ADDRESS_ID")
    private Long ipAddressId;

    @Id
    @Column(name = "HTTP_MESSAGE_ID")
    private Long httpMessageId;

    @ManyToOne
    @PrimaryKeyJoinColumn(name = "ipAddressId", referencedColumnName = "IP_ADDR_ID_2")
    //    @JoinColumn(name = "ipAddressId", updatable = false, insertable = false, referencedColumnName = "IP_ADDR_ID_2")
    private Ip ip;

    @ManyToOne
    @PrimaryKeyJoinColumn(name = "httpMessageId", referencedColumnName = "S_ID_2")
    //    @JoinColumn(name = "httpMessageId", updatable = false, insertable = false, referencedColumnName = "S_ID_2")
    private Message message;


//    @ManyToOne
    @JoinColumn(name = "IP_ADDRESS_2", updatable = false, insertable = false, referencedColumnName = "IP_ADDRESS_2")
    private String address;

    @JoinColumn(name = "STATUS_CODE", updatable = false, insertable = false, referencedColumnName = "STATUS_ID_2")
    private Long code;

    @JoinColumn(name = "STATUS_MESSAGE", updatable = false, insertable = false, referencedColumnName = "STATUS_2")
    private String codeMessage;


    public IMAssociation() 
    

    public IMAssociation(Long code, String codeMessage) 
        this.code = code;
        this.codeMessage = codeMessage;
    


List&lt;IMAssociation&gt; 是通过代码生成的,

List<IMAssociation> imAssociations = new ArrayList<>();

for(int j =0; j < 5; j++)

     IMAssociation imAssociation = new IMAssociation(Long.valueOf(integerListEntry.getKey()),
                                            message);
    imAssociations.add(imAssociation);



Ip ip = new Ip('127.0.0.1', imAssociations); 

List<Ip> ips = new ArrayList<>();
ips.add(ip);

当我尝试在数据库中持久化 List&lt;Ip&gt; 时,我收到以下错误,

Caused by: org.springframework.orm.jpa.JpaSystemException: Could not set field value [POST_INSERT_INDICATOR] value by reflection : [class com.ef.entity.IMAssociation.id] setter of com.ef.entity.IMAssociation.id; nested exception is org.hibernate.PropertyAccessException: Could not set field value [POST_INSERT_INDICATOR] value by reflection : [class com.ef.entity.IMAssociation.id] setter of com.ef.entity.IMAssociation.id


Caused by: org.hibernate.PropertyAccessException: Could not set field value [POST_INSERT_INDICATOR] value by reflection : [class com.ef.entity.IMAssociation.id] setter of com.ef.entity.IMAssociation.id
    at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:58) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:419) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:97) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:765) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:758) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:278) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at sun.reflect.GeneratedMethodAccessor19.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]


Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field com.ef.entity.IMAssociation.id to org.hibernate.id.IdentifierGeneratorHelper$2
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_144]
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_144]
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_144]

这里有什么问题?

Update

我已经更改了IMAssociation 类及其下面提供的内容,

@Entity
@Table(name = "IP_HTTP_MESSAGE")
//@IdClass(AssociationId.class)
public class IMAssociation implements Serializable 

//    @Id
//    @GeneratedValue(strategy = GenerationType.IDENTITY)
//    private Long id;

    @Id
    @Column(name = "IP_ADDRESS_ID")
    private Long ipAddressId;

    @Id
    @Column(name = "HTTP_MESSAGE_ID")
    private Long httpMessageId;

    @ManyToOne
    @PrimaryKeyJoinColumn(name = "IP_ADDRESS_ID", referencedColumnName = "IP_ADDR_ID_2")
//    @JoinColumn(name = "ipAddressId", updatable = false, insertable = false, referencedColumnName = "IP_ADDR_ID_2")
    private Ip ip;

    @ManyToOne
    @PrimaryKeyJoinColumn(name = "HTTP_MESSAGE_ID", referencedColumnName = "S_ID_2")
//    @JoinColumn(name = "httpMessageId", updatable = false, insertable = false, referencedColumnName = "S_ID_2")
    private Message message;


    //    @ManyToOne
    @JoinColumn(name = "IP_ADDRESS_2", updatable = false, insertable = false, referencedColumnName = "IP_ADDRESS_2")
    private String address;

    @JoinColumn(name = "STATUS_CODE", updatable = false, insertable = false, referencedColumnName = "STATUS_ID_2")
    private Long code;

    @JoinColumn(name = "STATUS_MESSAGE", updatable = false, insertable = false, referencedColumnName = "STATUS_2")
    private String codeMessage;


    public IMAssociation() 
    

    public IMAssociation(Long code, String codeMessage) 
        this.code = code;
        this.codeMessage = codeMessage;
    

现在,我在运行应用程序时收到以下错误,

Caused by: javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.ef.entity.IMAssociation#IMAssociation, ipAddressId=null, httpMessageId=null, ip=null, message=null, address='null', code=404, codeMessage='404_Not Found']
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1664) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1152) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at sun.reflect.GeneratedMethodAccessor19.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]

【问题讨论】:

请看***.com/questions/16124638/… 您的实体IMAssociation 中有多个主键。您要么声明 @IdClass@EmbeddedId 以具有复合主键/复合键,但我没有看到您使用过其中任何一个。 另外,您在这里错误地使用了@PrimaryKeyJoinColumnname 属性应该映射到表的物理列名,而不是某些实体属性。所以应该是@PrimaryKeyColumn(name="IP_ADDRESS_ID", referencedColumnName = "IP_ADDR_ID_2")@PrimaryKeyColumn(name="HTTP_MESSAGE_ID", referencedColumnName = "S_ID_2") 我尝试在Ip 类的顶部使用@IdClass(AssociationId.class),其中AssociationId 实现Serializable。这并不能解决问题,并且仍然提供相同的错误。使用@EmbeddedId 的正确方法是什么?我使用它而不是 @Id 并得到一些错误 @Ish 我实际上已经尝试了我提供的所有建议,但仍然遇到同样的错误。如果您现在有一个开放的 IDE,您介意提供一个可行的解决方案吗? 【参考方案1】:

这是你的问题: https://hibernate.atlassian.net/browse/HHH-6044

SO 中的类似帖子:Hibernate @GeneratedValue in a composite key

这里有 3 个选项:

    您仍然可以实现复合键,但您必须删除 IMAssociation 实体中自动生成的 ID。您的复合键将仅由 2 个属性组成 - ipAddressIdhttpMessageId,它们分别是来自您的 AddressMessage 实体的派生键/外键。 或者您实现单个主键:在这里您可以通过 IDENTITY 策略使用 id 自动生成,但您必须删除您声明的其他 id 字段 - ipAddressIdhttpMessageId。 如果您仍想保留 3 个 Id 字段 - idipAddressIdhttpMessageId,则删除 id 自动生成(@GeneratedValue 注释)并手动为您的 IMAssociation 实体分配一个 id 值.

【讨论】:

我尝试了第一个选项并得到了一些错误。我在更新的问题中提供了错误堆栈。如果你能提供一个可行的解决方案,我真的很感激【参考方案2】:

可能不需要ipAddressIdhttpMessageId 我认为包含这些值的列是由@PrimaryKeyJoinColumn 注释在dblevel 中自动生成的,并且可以通过ip.getMessage()IMAssociation 中访问该值和ip.getId()

【讨论】:

这可以正常工作,但令人惊讶的是,我发现地址列中没有任何值是有线的 删除 String address 并使用 ip.getAddress(),我猜

以上是关于org.springframework.orm.jpa.JpaSystemException:无法通过反射设置字段值 [POST_INSERT_INDICATOR] 值的主要内容,如果未能解决你的问题,请参考以下文章