2014-12-22 2 views
1

У меня проблема с отображением с использованием спящего режима. Две таблицы матрицы и matrix_value. enter image description hereHibernate не передает сгенерированный идентификатор

CREATE TABLE matrix (
    matrix_id  INT AUTO_INCREMENT, 
    number_of_rows INT NOT NULL DEFAULT 0, 
    number_of_cols INT NOT NULL DEFAULT 0, 
    PRIMARY KEY (matrix_id) 
) ENGINE =InnoDB; 

CREATE TABLE matrix_value (
    id   INT AUTO_INCREMENT, 
    matrix_id INT NOT NULL DEFAULT 0, 
    row_id  INT NOT NULL DEFAULT 0, 
    column_id INT NOT NULL DEFAULT 0, 
    matrix_val INT NOT NULL DEFAULT 0, 
    PRIMARY KEY (id), 
    CONSTRAINT FK_matrix_value_matrix 
    FOREIGN KEY (matrix_id) REFERENCES matrix (matrix_id) 
    ON UPDATE CASCADE ON DELETE CASCADE 
) ENGINE =InnoDB; 

После генерации из matrix_values ​​и вставки матрицы строк и столбцов она должны автоматически принимать matrix_id и передать его matrix_values, но он бросает

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'matrix_id' cannot be null 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 

Также он добавляет к столу " матрица 'дополнительный столбец' matrixValues ​​', заполненный нулем.

Вот метод

public void fillMatrixWithValues(MatrixValue[] values) throws Exception {   
    Session session = HibernateUtils.openSession(); 
    Transaction tx = null; 
    try { 
     tx = session.getTransaction(); 
     tx.begin(); 
     if (values != null && values.length != 0) { 
      for (int i = 0; i < values.length; i++) { 
       session.saveOrUpdate(values[i]); 
      } 
      tx.commit(); 
     }  
    } catch (HibernateException e) { 
     if (tx != null) { 
      tx.rollback(); 
     } 
     logger.error("Error fillMatrixWithValues-method: " + e.getMessage()); 
     throw e; 
    }  finally { 
     session.close(); 
    } 
} 

Матрица (POJO)

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@GenericGenerator(name = "increment", strategy = "increment") 
@Column(name = "matrix_id", unique = true, nullable = false) 
private int matrixId; 

@Column(name = "number_of_rows", unique = false, nullable = false) 
private int numberOfRows; 

@Column(name = "number_of_cols", unique = false, nullable = false) 
private int numberOfCols; 

@OneToMany (mappedBy= "matrix", fetch = FetchType.EAGER) 
@Transient 
private List<MatrixValue> values; 

MatrixValues ​​(POJO)

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@GenericGenerator(name = "increment", strategy = "increment") 
@Column(name = "id", unique = true, nullable = false) 
private int id; 

@PrimaryKeyJoinColumn 
@Column(name = "matrix_id", unique = false, nullable = false, insertable = false, updatable = false) 
private int matrixId; 

@Column(name = "row_id", unique = false, nullable = false) 
private int rowId; 

@Column(name = "column_id", unique = false, nullable = false) 
private int columnId; 

@Column(name = "matrix_val", unique = false, nullable = false) 
private int value; 

@ManyToOne 
@JoinColumn(name = "matrix_id") 
private Matrix matrix; 

getters and setters 

ч ibernate.xml

<hibernate-configuration> 
    <session-factory> 
     <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="connection.url">jdbc:mysql://localhost/matrixbase</property> 
     <property name="connection.username">root</property> 
     <property name="connection.password">root</property> 
     <property name="connection.pool_size">10</property> 
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
     <property name="show_sql">true</property> 
     <property name="hbm2ddl.auto">update</property> 
     <property name="hibernate.connection.autocommit">false</property> 
     <property name="current_session_context_class">thread</property> 
     <property name="hibernate.jdbc.batch_size">30</property> 
     <property name="hibernate.jdbc.batch_versioned_data">true</property> 
     <property name="hibernate.jdbc.use_get_generated_keys">true</property> 

     <mapping class="kuidin.task5.entity.Matrix" /> 
     <mapping class="kuidin.task5.entity.MatrixValue" /> 
<hibernate-configuration> 

Что не так? Спасибо заранее.

+0

Поскольку ошибка связана с Ограничением (только в MATRIX_VALUES), кажется, что когда вызывается 'saveOrUpdate',' matrix_id' не заполняется. Вы посмотрели на то, что создает «MatrixValue [] values» и убедитесь, что оно заполнено? Если да, добавьте этот код. – Ascalonian

+0

Спасибо за ответ. Ну, я уверен, что ** MatrixValue [] значения ** заполняется. Это показано на моем jsp. И каждое «значение» имеет matrix_id = 0. И после вставки в должен иметь 'matrix_id' euqaled к id объекта Matrix. В jdbc это было сделано с помощью get_generated_id. В hibernate я добавил это свойство. – Devour

+0

Извините, я имел в виду, что создает 'values', что он заполняет поле' matrixId'. Странно, что это всегда одно и то же значение. – Ascalonian

ответ

0

Удалите поле @Transient и matrix_id (с аннотациями) в классе MatrixValues. Вам тоже не нужно.

Объяснение:

  1. в matrixValues ​​коллекция не преходяще. Он должен сохраняться, хотя Матрица не является «владельцем» ассоциации (когда сохраняющийся Hibernate будет смотреть на отображаемое поле, чтобы найти значение для сохранения, хотя это должно дать одно и то же значение), это называется «обратной» стороной (двунаправленной) ассоциации.
  2. столбец matrix_id в matrixValues ​​будет заполнен идентификатором матрицы, назначенной полю матрицы. Добавление дополнительного поля является излишним и аннотирует его, поскольку @PrimaryKeyJoinColumn просто мертв неправильно: столбец не является частью первичного ключа таблицы, которая его содержит.
+0

Как я получу значения из таблицы ** matrix_values ​​**, если я удалю поле matrix_id в классе MatrixValues?Теперь у меня есть метод ** MatrixValue [] getValuesById (int matrixId) ** где ** values ​​= session.createQuery ("из значений MatrixValue, где values.matrixId =" + matrixId) .list(); ** Без matrix_id это doesn ' т работы. Тогда как мне нужно аннотировать поля? Сори, я новичок в спящем режиме. – Devour

+0

Ну, коллекция матричных значений в матрице загружена с нетерпением, поэтому вы можете просто получить матрицу по ее идентификатору и получить значения, обратившись к коллекции. –

+0

Да, я пробовал. Но не везде этот подход подходит. – Devour

Смежные вопросы