0

我有一张桌子ConfigManagementSettings和一张桌子DeviceGroup,如下所示:

@Entity
@Table(name = "device_group")
public class DeviceGroup extends devicemanage.repository.base.entity.base.EntityBase implements Serializable
{
    private static final long   serialVersionUID    = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long            id;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "create_time", nullable = false)
    private Calendar        createTime;
    @Column(name = "domain_id", nullable = false)
    private int             domainId;
    @Column(nullable = false)
    private String          name;
    private String          remark;
    @Column(nullable = false)
    private Integer         type;
    @Version
    private Integer         version;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "deviceGroupParent", fetch = FetchType.LAZY)
    private ConfigManagementSettings    configManagementCollection;

}

@Entity
@Table(name = "config_management_settings")
public class ConfigManagementSettings extends EntityBase implements Serializable
{
    private static final long               serialVersionUID    = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long                            id;
    @Version
    private Integer                         version;
    @Column(name = "group_id", nullable = false, unique = true)
    private Long                            groupId;
    private byte[]  settings;
    @Column(name = "sequential_order", nullable = false)
    private Integer                         sequentialOrder;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "group_id")
    private DeviceGroup                     deviceGroupParent;

    @Transient
    private int                             order;
}

当我进行如下简单的单元测试时

    @Test
    public void testConfigManagementSettings() throws Exception
    {
        ConfigManagementSettings config = new ConfigManagementSettings();
        config.setGroupId(3L);
        config.setSequentialOrder(1);
        configManagementSettingsDao.save(config);       
    }

我得到了 InvalidStateException 如下

Caused by: <openjpa-2.2.2-r422266:1468616 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2347)
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2184)
at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2082)
at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2000)
at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1524)
at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:933)
at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:570)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:515)
... 45 more
Caused by: <openjpa-2.2.2-r422266:1468616 fatal user error> org.apache.openjpa.persistence.InvalidStateException: Attempt to set column "config_management_settings.group_id" to two different values: (null)"null", (class java.lang.Long)"3" This can occur when you fail to set both sides of a two-sided relation between objects, or when you map different fields to the same column, but you do not keep the values of these fields in synch.
    at org.apache.openjpa.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:344)
    at org.apache.openjpa.jdbc.sql.RowImpl.setObject(RowImpl.java:510)
    at org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:158)
    at org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:109)
    at org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy.insert(HandlerFieldStrategy.java:130)
    at org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:623)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:239)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:166)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:97)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:78)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:732)
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131)
    ... 53 more

但是,我还有另外两个表 Subtask 和 SubtaskResult 如下:

@Entity
@Table(name = "subtask")
public class Subtask extends devicemanage.repository.base.entity.base.EntityBase implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long        id;
    @Column(name = "domain_id", nullable = false)
    private Integer     domainId;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "finish_time")
    private Calendar    finishTime;
    @Column(nullable = false)
    private Integer     state;
    @Column(name = "task_id", nullable = false)
    private Long        taskId;
    @Column(name = "task_type", nullable = false, length = 1)
    private String      taskType;
    @Column(length = 256)
    private String      remark;
    // @Version
    private Integer     version;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "subtaskParent", fetch = FetchType.LAZY)
    private SubtaskResult resultOfSubtask;
}

@Entity
@Table(name = "subtask_result")
public class SubtaskResult extends EntityBase implements Serializable
{
    private static final long   serialVersionUID    = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long                id;
    @Version
    private Integer             version;
    @Column(name = "subtask_id", unique=true, nullable = false)
    private Long                subtaskId;
    private String              results;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "subtask_id")
    private Subtask             subtaskParent;
}

还有一个简单的单元测试我做了如下

@Test
public void testSubtaskResult() throws Exception
{
    SubtaskResult subtaskResult = new SubtaskResult();
    subtaskResult.setSubtaskId(33L);
    subtaskResult.setResults("test");
    subtaskResultDao.save(subtaskResult);
}

它可以正常工作并成功地保留实体。

我有什么遗漏吗?为什么这两种情况有不同的行为?

任何帮助表示赞赏。

4

0 回答 0