Ну, посмотрим
Ваше исключительное (и известное) сообщение:
repeated column in mapping for entity:
column: SURVEY_NUM (should be mapped with insert="false" update="false")
Где находится столбец SURVEY_NUM?
1º Поле issDivision хранит столбец внешнего ключа с именем SURVEY_NUM
@ManyToOne
@JoinColumns({
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE", insertable=false, updatable=false),
@JoinColumn(name="SURVEY_NUM", referencedColumnName="SURVEY_NUM", insertable=false, updatable=false)})
private IssDivision issDivision;
Теперь посмотрите следующее отображение ( см. Id и accountNumber совместно используют один и тот же столбец )
@Entity
public class Account {
private Integer id;
private Integer accountNumber;
@Id
@Column(name="ACCOUNT_NUMBER")
public Integer getId() {
return this.id;
}
@Column(name="ACCOUNT_NUMBER")
public Integer getAccountNumber() {
return this.accountNumber;
}
}
Теперь давайте сделаем следующее
Account account = new Account();
account.setId(127359);
account.setAccountNumber(null);
entityManager.persist(account);
Hibernate попросит вас
Какое свойство мне следует сохранить , если оба свойства имеют один и тот же столбец ??? И, как я вижу, свойство id хранит ненулевое значение, а accountNumber - нулевое значение.
Должен ли я выполнить такой запрос ???
INSERT INTO ACCOUNT (ACCOUNT_NUMBER, ACCOUNT_NUMBER) VALUES (127359, NULL);
Это не имеет смысла. Следовательно, это неправильный запрос SQL;
Из-за этого вы видите это милое сообщение
повторный столбец ... бла, бла, бла ... (должен отображаться с помощью insert = "false" update = "false")
Итак, Полагаю, ваш составной первичный ключ с именем IssTESTPK также хранит столбец с именем SURVEY_NUM. И не очень хорошая идея вы определяете составное свойство первичного ключа как insert = "false" update = "false". Избегайте сильной головной боли.
Имейте в виду: если более одного свойства совместно используют один и тот же столбец, определите одно из них как inserttable = false, updatable = false. Ничего другого .
Я думаю, ваш класс составного первичного ключа должен выглядеть следующим образом
@Embeddable
public class IssTESTPK implements Serializable {
// Ops... Our missing field which causes our Exception (repeated column... blah, blah, blah...)
@Column(name="SURVEY_NUM", nullable=false)
private Integer property;
private Integer otherProperty;
private Integer anotherProperty;
// required no-arg constructor
public IssTESTPK() {}
// You must implement equals and hashcode
public boolean equals(Object o) {
if(o == null)
return false;
if(!(o instanceof IssTESTPK))
return false;
IssTESTPK other = (IssTESTPK) o;
if(!(getProperty().equals(other.getProperty())))
return false;
if(!(getOtherProperty().equals(other.getOtherProperty())))
return false;
if(!(getAnotherProperty().equals(other.getAnotherProperty())))
return false;
return true;
}
// NetBeans or Eclipse will worry about it
public int hashcode() {
// hashcode code goes here
}
}
UPDATE
Перед тем как продолжить
Hibernate не поддерживает автоматическое создание составного первичного ключа
Вы должны предоставить свои значения перед сохранением. Имейте это в виду
Посмотрим составной первичный ключ сотрудника
@Embeddable
public class EmployeeId implements Serializable {
@Column(name="EMPLOYEE_NUMBER")
private String employeeNumber;
@Column(name="SURVEY_NUMBER")
private BigInteger surveyNumber;
// getter's and setter's
// equals and hashcode
}
1º Перед сохранением сотрудника, вы должны предоставить его значения. Как сказано выше, Hibernate не поддерживает автоматическую генерацию составного первичного ключа
2º Hibernate не позволяет обновлять (составной) первичный ключ. Это не имеет смысла.
3º Его значения не могут быть нулевыми
Итак, согласно описанному выше, наш EmployeeId может быть записан как
@Embeddable
public class EmployeeId implements Serializable {
@Column(name="EMPLOYEE_NUMBER", nullable=false, updatable=false)
private String employeeNumber;
@Column(name="SURVEY_NUMBER", nullable=false, updatable=false)
private BigInteger surveyNumber;
// getter's and setter's
// equals and hashcode
}
Как сказал
когда более одного свойства совместно используют один и тот же столбец, определите одно из них как inserttable = false, updatable = false. Ничего другого
Но мы не можем пометить составное свойство первичного ключа как вставляемое = ложное, обновляемое = ложное , поскольку Hibernate использует его для сохранения нашей сущности
Поскольку Hibernate будет использовать наше составное свойство первичного ключа, называемое surveyNumber (и его столбец SURVEY_NUMBER), для выполнения SQL-операции с базой данных, нам нужно переписать наше свойство деления @ManyToOne (и его столбец внешнего ключа с именем SURVEY_NUMBER) как вставляемый = false, обновляемый = false
// Employee.java
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE"),
@JoinColumn(name="SURVEY_NUMBER", referencedColumnName="SURVEY_NUMBER", insertable=false, updatable=false)})
private Division division;
4º Если у вас есть составной внешний ключ, мы не можем смешивать вставляемый-не вставляемый или обновляемый-не обновляемый.
Что-то вроде
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
// I can be updatable
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE", insertable=false),
// And i can be insertable
@JoinColumn(name="SURVEY_NUMBER", referencedColumnName="SURVEY_NUMBER", updatable=false)})
private Division division;
В противном случае Hibernate будет жаловаться
Смешивание вставляемых и не вставляемых столбцов в свойстве недопустимо
Из-за этого столбец составного внешнего ключа с именем DIVISION_CODE также должен быть помечен как вставляемый = ложь, обновляемый = ложь, чтобы избежать исключения, показанного выше
// Employee.java
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE", insertable=false, updatable=false),
@JoinColumn(name="SURVEY_NUMBER", referencedColumnName="SURVEY_NUMBER", insertable=false, updatable=false)})
private Division division;
Поскольку мы больше не можем обновлять столбец DIVISION_CODE, наше свойство деления ведет себя как константа . Затем вы подумываете о создании нового свойства с именем DivisionCode для изменения столбца DIVISION_CODE, как показано ниже
// Employee.java
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE", insertable=false, updatable=false),
@JoinColumn(name="SURVEY_NUMBER", referencedColumnName="SURVEY_NUMBER", insertable=false, updatable=false)})
private Division division;
// Wow, now i expect i can change the value of DIVISION_CODE column
@Column(name="DIVISION_CODE")
private BigInteger divisionCode;
Ну, посмотрим. Предположим, у нас есть следующая таблица DIVISION
DIVISION TABLE
DIVISION_CODE SURVEY_NUMBER
1 10
2 11
3 12
4 13
5 14
помните: между отделом и сотрудником существует ограничение по внешнему ключу
Вы думаете о
Не могу изменить свойство деления из-за вставляемого = ложного, обновляемого = ложного. Но я могу изменить свойство DivisionCode (и его столбец DIVISION_CODE) как способ изменить столбец внешнего ключа с именем DIVISION_CODE
Вы делаете следующий код
* +1147 * employee.setDivisionCode (7);
Ух ты, смотри выше в DIVISION_TABLE. Есть ли какое-то значение в столбце DIVISION_CODE, равное 7?
ответ ясен: нет (вы увидите ОГРАНИЧЕНИЕ НАРУШЕНИЯ)
Итак, это противоречивое отображение . Hibernate не позволяет этого.
С уважением,