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

ただし、以下のように、別の 2 つのテーブル 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);
}

エンティティを永続化するために正常に機能します。

私が見逃しているものはありますか?これら 2 つのケースの動作が異なるのはなぜですか?

どんな助けでも大歓迎です。

4

0 に答える 0