gpt4 book ai didi

java - hibernate 更新JPA外键

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:09:56 26 4
gpt4 key购买 nike

我的 jpa 如下所示

public class TESTClass implements Serializable {

...

private String name;

@EmbeddedId
protected IssTESTPK issTESTPK;

@ManyToOne(optional=false)
@JoinColumns({
@JoinColumn(name="DIVISION_CODE", referencedColumnName="DIVISION_CODE", nullable=false, insertable=false, updatable=false),
@JoinColumn(name="SURVEY_NUM", referencedColumnName="SURVEY_NUM", nullable=false, insertable=false, updatable=false)})
private IssDivision issDivision;

}

如果我更改“名称”并调用合并,它能够更新到数据库中,但是当我更改 issDivision 并调用合并时,它不会更新数据库。如何解决这个问题?


这与我使用的是 embededId(复合主键)有关吗?

已更新

如果我设置 upadted=true,我会得到以下错误

ERROR - ContextLoader.initWebApplicationContext(215) | Context initialization fa
iled
org.springframework.beans.factory.BeanCreationException: Error creating bean wit
h name 'sessionFactory' defined in ServletContext resource [/WEB-INF/application
Context.xml]: Invocation of init method failed; nested exception is org.hibernat
e.MappingException: Repeated column in mapping for entity: com.compay.test.model
.TESTClass column: SURVEY_NUM (should be mapped with insert="false" update="fa
lse")
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe
an(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
preInstantiateSingletons(DefaultListableBeanFactory.java:423)
at org.springframework.context.support.AbstractApplicationContext.finish
BeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:380)
at org.springframework.web.context.ContextLoader.createWebApplicationCon
text(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationConte
xt(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitiali
zed(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
342)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
1)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)

at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.ja
va:627)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.j
ava:553)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488
)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)

at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)

at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443
)
at org.apache.catalina.core.StandardService.start(StandardService.java:5
16)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710
)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.

最佳答案

好吧,让我们看看

您的异常(和著名)消息是

repeated column in mapping for entity:
column: SURVEY_NUM (should be mapped with insert="false" update="false")

SURVEY_NUM 列位于何处?

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 会问你

Which property should i persist whether both properties shares the same column ??? And as i can see, id property stores a non-null value and accountNumber a null value.

我应该执行这样的查询吗???

INSERT INTO ACCOUNT (ACCOUNT_NUMBER, ACCOUNT_NUMBER) VALUES (127359, NULL);

没有意义。因此,这是一个错误的SQL查询;

正因为如此,你看到了这个好消息

repeated column... blah, blah, blah... (should be mapped with insert="false" update="false")

所以我想您名为 IssTESTPK 的复合主键还存储名为 SURVEY_NUM 的列。 这不是一个好主意,您将复合主键属性定义为 insert="false"update="false"。避免很多头痛。

请记住:当多个属性共享同一列时,将其中之一定义为 insertable=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
}

}

更新


继续之前

Hibernate does not support automatic generation of compound primary key

必须在保存前提供它的值。记在心里

让我们看看员工复合主键

@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

}

在保存 Employee 之前,您必须提供它的值。上面说了,Hibernate不支持自动生成复合主键

Hibernate 不允许您更新(复合)主键这没有意义。

其值不能为空

所以,根据上面的描述,我们的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

}

如前所述

when more than one property shares the same column, define one of them as insertable=false, updatable=false. Nothing else

但是我们不能将复合主键属性标记为 insertable=false, updatable=false 因为 Hibernate 使用它来保存我们的实体

由于 Hibernate 将使用名为 surveyNumber 的复合主键属性(及其 SURVEY_NUMBER 列)对数据库执行 SQL 操作,因此我们需要重写我们的 @ManyToOne 分部属性(及其名为 SURVEY_NUMBER 的外键列)为 insertable=假的,可更新的=假的

// 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;

当您有复合外键时,我们不能混合可插入-不可插入或可更新-不可更新。

有点像

@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 会报错

Mixing insertable and non insertable columns in a property is not allowed

正因为如此,它的名为 DIVISION_CODE 的复合外键列也应该标记为 insertable=false, updatable=false 以避免上面显示的异常

// 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 TABLE

DIVISION TABLE
DIVISION_CODE SURVEY_NUMBER
1 10
2 11
3 12
4 13
5 14

记住:Division 和 Employee 之间有一个外键约束

你想到

I can not change division property because of insertable=false, updatable=false. But i can change divisionCode property (and its DIVISION_CODE column) as a way to change the foreign key column called DIVISION_CODE

您执行以下代码

员工.setDivisionCode(7);

哇哦,请参阅上面的 DIVISION_TABLE。 DIVISION_CODE 列中是否有某个值等于 7?

答案很明确:否(您会看到违反约束)

所以,这是一个不一致的映射。 Hibernate 不允许这样做。

问候,

关于java - hibernate 更新JPA外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2468106/

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