Почему при слиянии в eclipselink появляются ошибки «Duplicate entry» для связанных объектов? - PullRequest
0 голосов
/ 15 июля 2011

У меня есть класс сущностей, который содержит карту пар ключ-значение, которые находятся в другой таблице, и для данной сущности таких пар может не быть. Соответствующий код для классов сущностей приведен ниже.

Теперь, когда я вставляю такую ​​сущность с persist(), затем добавляю пары ключ-значение, а затем сохраняю ее с merge(), я получаю повторяющиеся ошибки ввода для связанной таблицы, в которой хранятся пары ключ-значение. Я пытался отложить вставку до тех пор, пока не были добавлены ключи, чтобы был только один вызов persist(). Это привело к дублированию ошибок ввода, содержащих пустой (нулевой) идентификатор в столбце внешнего ключа (ixSource).

Я проследил за процессом в отладчике и обнаружил, что eclipselink, похоже, не понимает каскадирования. Пока он обновляет сущность, он выполняет вызовы, которые обновляют связанную таблицу. Тем не менее, он также добавляет эти операции в очередь, которая обрабатывается впоследствии, то есть, когда возникают повторяющиеся ошибки ввода. Я пробовал CascadeType.ALL и MERGE, без разницы.

Я использую статическое плетение, если это имеет значение.

Вот код сущности, сокращенный для краткости:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "sType")
@Table(name = "BaseEntity")
public abstract class BaseEntity extends AbstractModel
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ix")
    private long _ix;
}

@Entity
@Table(name = "Source")
public class Source extends BaseEntity
{
    @OneToMany(cascade = CascadeType.MERGE)
    @JoinTable(name = "SourceProperty", joinColumns = { @JoinColumn(name = "ixSource")     })
    @MapKey(name = "sKey")
    private Map<String, SourceProperty> _mpKeys;

    // ... there's more columns that probably don't matter ...
}

@Entity
@Table(name = "SourceProperty")
@IdClass(SourcePropertyKey.class)
public class SourceProperty
{
    @Id
    @Column(name = "sKey", nullable = false)
    public String sKey;

    @Id
    @Column(name = "ixSource", nullable = false)
    public long   ixSource;

    @Column(name = "sValue", nullable = true)
    public String sValue;
}

public class SourcePropertyKey implements Serializable
{
    private final static long serialVersionUID = 1L;
    public String             sKey;
    public long               ixSource;

    @Override
    public boolean equals(Object obj)
    {
        if (obj instanceof SourcePropertyKey) {
            return this.sKey.equals(((SourcePropertyKey) obj).sKey)
                    && this.ixSource == ((SourcePropertyKey) obj).ixSource;
        } else {
            return false;
        }
    }
}

1 Ответ

0 голосов
/ 18 июля 2011

Я не вижу, как эти ошибки будут происходить. Не могли бы вы включить SQL и полное исключение.

Какую версию EclipseLink вы используете, пробовали ли вы последний выпуск?

Почему вы звоните слияния? Вы отсоединяете объекты посредством сериализации, если это один и тот же объект, вам не нужно вызывать слияние.

Это может быть проблема с @MapKey, это работает, если вы удалите это?

...