使用Hibernate通过其他唯一值而不是主键更新数据库中的行?

时间:2019-04-05 13:51:46

标签: java sql hibernate web-services dao

我正在编写REST Web服务。我创建下一个Author实体:

@Entity
@Table(name = "author")
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "authorId", unique = true, nullable = false)
    private int authorId;

    @Column(name = "authorName", nullable = false)
    private String name;

    @Column(name = "authorSurname")
    private String surname;

    @Column(name = "nationality")
    private String nationality;

    @Column(name = "age")
    private int age;

    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    private List<Book> bookList;

    public Author() {
    }

    public Author(int authorId, String name, String surname, String nationality, int age) {
        this.authorId = authorId;
        this.name = name;
        this.surname = surname;
        this.nationality = nationality;
        this.age = age;
    }
}

DB中的id值,就像DB内部一样使用主键来引用其他表。为了通过URL标识实体(例如/rest/Author/{authorId}),请使用其他值-authorId。我也没有在实体构造函数中使用它。 DAO updateAuthor方法如下:

public Author updateAuthor(Author author) {
    Session session = getSessionFactory().openSession();
    Transaction transaction = session.beginTransaction();
    session.update(author);
    transaction.commit();

    Author updated = (Author) session
            .createQuery("FROM Author WHERE authorId=" + author.getAuthorId())
            .uniqueResult();

    session.close();
    return updated;
}

但是它无法正常工作...当我尝试使用authorId = 4更新现有实体时:

Author author1 = authorDao.updateAuthor(new Author(4, "qweqwe", "qweqwe", "qweqwe", 1000));

获取下一个执行的HQL查询:

Hibernate: update author set age=?, authorId=?, authorName=?, nationality=?, authorSurname=? where id=?

和下一个例外:

Exception in thread "main" org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

如何解决此问题而不单独设置所有值?

2 个答案:

答案 0 :(得分:0)

我找到了解决方法!

只需从Author模型中删除id属性,然后在@Id值上粘贴authorId注释:

@Entity
@Table(name = "author")
public class Author {

    @Id
    @Column(name = "authorId", unique = true, nullable = false)
    private int authorId;

    @Column(name = "authorName", nullable = false)
    private String name;

    @Column(name = "authorSurname")
    private String surname;

    @Column(name = "nationality")
    private String nationality;

    @Column(name = "age")
    private int age;

    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    private List<Book> bookList;

    public Author(){
    }

    public Author(int authorId, String name, String surname, String nationality, int age) {
        this.authorId = authorId;
        this.name = name;
        this.surname = surname;
        this.nationality = nationality;
        this.age = age;
    }
}

因此,现在Hibarnate的准确度为idauthorId。 现在工作正常。

答案 1 :(得分:0)

您可以尝试一下  您的:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;

对此替换并尝试

@Column(name = "id", updatable = false, nullable = false)