gpt4 book ai didi

java - 当嵌入式键包含 SQL Server 上的标识列时,Hibernate 插入失败

转载 作者:搜寻专家 更新时间:2023-11-01 02:20:29 24 4
gpt4 key购买 nike

我正在尝试使用 hibernate 映射一个实体,但是使用 SQL Server,我无法继续。

详情如下。

SQL Server 实体

CREATE TABLE [dbo].[BOOK_EMBEDDED](

[row_id] [bigint] IDENTITY(1,1) NOT NULL,

[group_no] [int] NOT NULL,

[book_name] [varchar](255) NULL,

CONSTRAINT [PK_BOOK_EMBEDDED] PRIMARY KEY CLUSTERED

(

[group_no] ASC,

[row_id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

=============================

嵌入 key

----------------------------

@Embeddable 

public class EmbeddedKey implements Serializable {


private static final long serialVersionUID = 1L;



@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name = "row_id")

private Long rowId;



@Column(name = "group_no")

private int groupNo;



public Long getRowId() {

return rowId;

}



public void setRowId(Long rowId) {

this.rowId = rowId;

}



public static long getSerialversionuid() {

return serialVersionUID;

}



@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = (int) (prime * result + rowId);

result = prime * result + groupNo;

return result;

}



@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

EmbeddedKey other = (EmbeddedKey) obj;

if (rowId != other.rowId)

return false;

if (groupNo != other.groupNo)

return false;

return true;

}



@Override

public String toString() {

return this.getRowId() + " " + this.getGroupNo() + " ";

}



public int getGroupNo() {

return groupNo;

}



public void setGroupNo(int groupNo) {

this.groupNo = groupNo;

}



}

实体

----------------

@Entity(name = "BOOK_EMBEDDED") 

public class BookMySQL implements Serializable {



/**

*

*/

private static final long serialVersionUID = 1L;



@Column(name = "BOOK_NAME")

private String book_Name;



@EmbeddedId

private EmbeddedKey key;



public BookMySQL() {

}



public String getBook_Name() {

return book_Name;

}



public void setBook_Name(String book_Name) {

this.book_Name = book_Name;

}



public static long getSerialversionuid() {

return serialVersionUID;

}



public EmbeddedKey getKey() {

return key;

}



public void setKey(EmbeddedKey key) {

this.key = key;

}



@Override

public String toString() {

return this.getKey().toString() + " " + this.getBook_Name();

}



}

实体管理类

--------------------------------

public class LocalEntityManager { 

private static EntityManagerFactory emf;

private static EntityManager em;



private LocalEntityManager() {

}



public static EntityManager getEntityManger() {

if (emf == null) {

synchronized (LocalEntityManager.class) {

if (emf == null) {

emf = Persistence.createEntityManagerFactory("BookEntities");

em = emf.createEntityManager();

}

}

}

return em;

}

}

图书服务

--------------------

public class MySQLBookService { 



public Long persistBook(String bookName) {

EmbeddedKey key = new EmbeddedKey();

key.setGroupNo(1);



BookMySQL book = new BookMySQL();

book.setBook_Name(bookName);

book.setKey(key);



EntityManager em = LocalEntityManager.getEntityManger();

EntityTransaction tx = em.getTransaction();

tx.begin();

em.persist(book);

tx.commit();

em.close();



return book.getKey().getRowId();

}



public BookMySQL findBook(int bookId) {

EntityManager em = LocalEntityManager.getEntityManger();

EmbeddedKey key = new EmbeddedKey();

key.setGroupNo(1);

key.setRowId(1L);

BookMySQL bookMySQL = em.find(BookMySQL.class, key);

System.out.println(bookMySQL);

return bookMySQL;

}



public static void main(String... args) {

MySQLBookService bookService = new MySQLBookService();

// bookService.findBook(1);



bookService.persistBook("Lord of the rings");

}



}

问题是我不能使用序列并通过执行它findBook 始终有效并持续失败并出现错误。

ERROR: Cannot insert explicit value for identity column in table 'BOOK_EMBEDDED' when IDENTITY_INSERT is set to OFF.

任何帮助将不胜感激。

最佳答案

让它工作的唯一方法是覆盖 SQLInsert 并欺骗期望设置标识符列的 Hibernate。如果您提供自己的自定义 INSERT 语句,则可以这样做,而不是将 rowId 设置为 null,而是设置版本:

@Entity(name = "BOOK_EMBEDDED")
@SQLInsert( sql = "insert into BOOK_EMBEDDED (BOOK_NAME, group_no, version) values (?, ?, ?)")
public static class Book implements Serializable {

@EmbeddedId
private EmbeddedKey key;

@Column(name = "BOOK_NAME")
private String bookName;

@Version
@Column(insertable = false)
private Integer version;

public EmbeddedKey getKey() {
return key;
}

public void setKey(EmbeddedKey key) {
this.key = key;
}

public String getBookName() {
return bookName;
}

public void setBookName(String bookName) {
this.bookName = bookName;
}
}

完成此更改后,您可以运行以下测试:

doInJPA(entityManager -> {

EmbeddedKey key = new EmbeddedKey();
key.setGroupNo(1);

Book book = new Book();
book.setBookName( "High-Performance Java Persistence");

book.setKey(key);

entityManager.persist(book);
});

doInJPA(entityManager -> {
EmbeddedKey key = new EmbeddedKey();

key.setGroupNo(1);
key.setRowId(1L);

Book book = entityManager.find(Book.class, key);
assertEquals( "High-Performance Java Persistence", book.getBookName() );
});

Hibernate 将生成正确的 SQL 语句:

Query:["insert into BOOK_EMBEDDED (BOOK_NAME, group_no, version) values (?, ?, ?)"], Params:[(High-Performance Java Persistence, 1, NULL(BIGINT))]

Query:["select compositei0_.group_no as group_no1_0_0_, compositei0_.row_id as row_id2_0_0_, compositei0_.BOOK_NAME as BOOK_NAM3_0_0_, compositei0_.version as version4_0_0_ from BOOK_EMBEDDED compositei0_ where compositei0_.group_no=? and compositei0_.row_id=?"], Params:[(1, 1)]

测试可在 GitHub 上获得.

关于java - 当嵌入式键包含 SQL Server 上的标识列时,Hibernate 插入失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46035660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com