Мы пытаемся использовать Hibernate с базой данных, которая использует lot составных ключей, и это вызывает у нас много головной боли.
К сожалению, мы не можем изменить схему, поэтому мы должны сделать много дополнительных сопоставлений между нашими полями. Мы ограничены в использовании JPA 1.0 и Hibernate 3.3.
Самая большая проблема
до сих пор мы имели дело с взаимно-однозначной связью между двумя сущностями, используя составной ключ из 2 значений, где таблицы имеют разные имена
для этих столбцов (БД имеет соглашение об именах, содержащее префикс для каждой таблицы в каждом столбце.)
Всякий раз, когда мы выполняем наш запрос, мы получаем это исключение:
Caused by: org.hibernate.TypeMismatchException Provided id of the wrong type for class com.business.entity.InvestorIssuerEmailEntity.
Expected: class com.business.entity.InvestorIssuerEmailEntityPK, got class com.business.entity.InvestorIssuerEntityPK;
Два класса для этих таблиц, InvestorIssuerEntity и InvestorIssuerEmailEntity, имеют необязательную связь @OneToOne
(в некоторых случаях у InvestorIssuer нет соответствующей записи в InvestorIssuerEmail):
@IdClass(InvestorIssuerEntityPK.class)
@Table(name = "T090_INVESTOR_ISSUER")
@Entity
InvestorIssuerEntity
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
(other fields omitted)
@OneToOne(optional = true)
@JoinColumns(value = {
@JoinColumn(name="T090_091_INVESTOR_ID", referencedColumnName = "T284_INVESTOR_ID", nullable = false, insertable = false, updatable = false),
@JoinColumn(name = "T090_102_ISSUER_ID", referencedColumnName = "T284_ISSUER_ID", nullable = false, insertable = false, updatable = false)
})
@NotFound(action = NotFoundAction.IGNORE)
private InvestorIssuerEmailEntity investorIssuerEmail;
...
InvestorIssuerEntityPK
@Id
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
private Long investorId;
@Id
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
private Long issuerId;
...
@IdClass(InvestorIssuerEmailEntityPK.class)
@Table(name = "T284_INVESTOR_ISSUER_EMAIL")
@Entity
InvestorIssuerEmailEntity
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
...
InvestorIssuerEmailEntityPK
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
Я пытался обойти проблему несоответствия типов, используя тот же класс, что и @EmbeddableId для двух сущностей, а затем используя @AttributeOverrides, например:
@Id
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "investorId",
column = @Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0)),
@AttributeOverride(name = "issuerId",
column = @Column(name = "T284_ISSUER_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0))
})
private InvestorIssuerId investorIssuerId;
Я сделал изменения только для этих двух сущностей, все еще используя подход @IdClass для других сущностей (это только случай использования @IdClass ИЛИ @EmbeddableId для ваших сущностей, а не для обеих?)
В итоге у нас возникли другие проблемы, такие как «Повторяющийся столбец в сопоставлении для сущности», поэтому мы вернулись к этому подходу, чтобы посмотреть, есть ли другие обходные пути для этого.
У кого-нибудь есть какие-нибудь решения, чтобы обойти эту проблему? Я просмотрел StackOverflow, но не сталкивался ни с одним случаем, когда составные ключи, используемые в ассоциации, имеют разные имена.
Примечание:
Даже после попытки предложенного ниже предложения мы все равно получаем эту ошибку: org.hibernate.MappingException: повторяющийся столбец в сопоставлении для сущности: com.business.entity.InvestorIssuerEntity: T090_091_INVESTOR_ID (должен отображаться с помощью insert = "false" update = "false ")
Я даже удалил ВСЕ ассоциации из InvestorIssuerEntity, и все еще получил ту же проблему. Ошибка исчезла только тогда, когда я удалил аннотацию @Column в классе составного ключа. Конечно, запросы не работали, потому что инвестор не был сопоставлен! Я не понимаю , где Hibernate находил «Повторяющийся столбец в отображении», поскольку я уже удалил все упоминания о T090_091_INVESTOR_ID, кроме составного ключа.
У нас есть другие ассоциации в InvestorIssuerEntity, которые выполняют объединение с теми же первичными ключами, но связанные сущности также имеют дополнительные столбцы в своих составных ключах. Как только вы используете @EmbeddedId, вы должны использовать их для всех сущностей? Мы все еще используем @IdClass для других классов. Но тогда как это повлечет за собой «повторяющуюся колонку»?