尝试将列设置为两个不同的值,并在OneToOne映射中导致InvalidStateException

时间:2015-11-21 10:18:44

标签: openjpa one-to-one joincolumn

我有一个表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);
}

它可以很好地成功地保持实体。

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

感谢任何帮助。

0 个答案:

没有答案