Hibnerate ManyToOne всегда каскадируется, когда его не просят

Скажем, у меня есть таблица User и таблица UserRecordInfo, которая сохраняет действия, предпринятые для изменения информации пользователя. например:

Пользователь:

ID пользователя | UserName |

| 1 | тест |

и UserRecordInfo:

| UserRecordInfoID | UserID | Действие | oldValue | newValue |

| 1 | 1 | обновить имя | oldTest | test2 |

| 2 | 1 | обновить имя | test2 | тест |

По-видимому, в Java при проектировании объектов я не хочу иметь поле UserRecordInfo в User, потому что для каждого пользователя могут быть сотни UserRecordInfo. Что у меня есть:

@Entity
@Table(name="User")
public class User {
private userName;
@Column(name = "userName")
    public String getUserName() {
        System.out.println("getting username");
        return userName;
    }
...
}

а также

@Entity
@Table(name="UserRecordInfo")
public class UserRecordInfo {
    private User user;

    @JoinColumn(name = "UserID")  // using javax.persistence.JoinColumn
    @ManyToOne(fetch = FetchType.LAZY) // using javax.persistence.ManyToOne
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

}

Я создаю новый UserRecordInfo:

User u = {get user from hibernate}
UserRecordInfo record = new UserRecordInfo();
record.setUser(u);
 .setNewName("test1");
...

Session session = DBSessionHandler.getSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        Serializable result = session.save(record);
        tx.commit();
        return result;
    }
    catch (HibernateException ex) {
        ex.printStackTrace(); 
        if (tx!=null) tx.rollback();
        throw ex;
    }
    finally {
        DBSessionHandler.close();
    }

однако, кажется, что всякий раз, когда я вставляю новый UserRecordInfo, пользовательский объект всегда касается (println всегда печатает "получение имени пользователя"). Почему это происходит? Я делаю что-то неправильно?

1 ответ

Решение

Попробуйте добавить атрибут "updatable=false" в аннотацию @JoinColumn.

Вы можете пометить тип выборки как 'Eager' для аннотации @ManyToOne.

Также я бы порекомендовал вам аннотировать поля вместо получателей.

Класс UserRecordInfo будет выглядеть так:

@Entity
@Table(name="UserRecordInfo")
public class UserRecordInfo {

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "UserID", nullable = false, updatable = false)
    @NotNull
    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

Документ для "обновляемых" читается как:

(Необязательно) Включен ли столбец в операторы SQL UPDATE, сгенерированные поставщиком сохраняемости.

что, кажется, дело, которое вы хотите решить

Другие вопросы по тегам