У меня есть класс сущностей, который содержит карту пар ключ-значение, которые находятся в другой таблице, и для данной сущности таких пар может не быть. Соответствующий код для классов сущностей приведен ниже.
Теперь, когда я вставляю такую сущность с 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;
}
}
}