Java – hibernate update JPA foreign key

New flag new flag new flag new flag new flag new flag new flag new flag new flag new flag new flag new flag new flag new flag new flag

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",updatable=false)})
    private IssDivision issDivision;

}

If I change to 'name' and call merge, it can update to the database, but when I change issdivision and call merge, it will not update the database X- 20045 X- 20045 X- 20045 X- 20045 200:

Is this related to my use of embeddedid (composite primary key)?

to update

If I set upadted = true, I get the following error

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.

Solution

Well, let's see

Your exceptional (and famous) news is

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

SURVEY_ Where is the num column?

The 1 º issdivision field stores a file named survey_ Foreign key column of num

@ManyToOne
@JoinColumns({
    @JoinColumn(name="DIVISION_CODE",updatable=false)})
private IssDivision issDivision;

Now look at the mapping below (see ID and accountnumber share the same column)

@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;
    }

}

Now let's do the following

Account account = new Account();
account.setId(127359);
account.setAccountNumber(null);

entityManager.persist(account);

Hibernate will ask you

Should I execute a query like this?

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

It makes no sense Therefore, this is an incorrect SQL query;

Because of this, you see the good news

So I think your composite primary key is called istestpk, and it also stores a key called query_ Num column Moreover, it is not a good idea for you to define the composite primary key attribute as insert = "false" and update = "false" Avoid a lot of headaches

Remember: when multiple attributes share the same column, define one of them as insertable = false and updatable = false Nothing else

I think your composite primary key class should be like this

@Embeddable
public class IssTESTPK implements Serializable {

    // Ops... Our missing field which causes our Exception (repeated column... 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
    }

}

UPDATE

Before continuing

Its value must be provided before saving Remember it

Let's take a look at employee composite keys

@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

}

1 º before saving an employee, you must provide its value As mentioned above, hibernate does not support automatic generation of composite primary keys

2 º hibernate does not allow you to update (compound) the primary key, which is meaningless

The value of 3 º cannot be empty

Therefore, as mentioned above, our employeeID can be written as

@Embeddable
public class EmployeeId implements Serializable {

    @Column(name="EMPLOYEE_NUMBER",updatable=false)
    private String employeeNumber;

    @Column(name="SURVEY_NUMBER",updatable=false)
    private BigInteger surveyNumber;

    // getter's and setter's

    // equals and hashcode

}

As mentioned above

However, we cannot mark the composite primary key attribute as insertable = false and updatable = false, because hibernate uses it to save our entities

Since hibernate will use the compound primary key attribute named surveynumber (and its query_number column) to perform SQL operations on the database, we need to rewrite the @ manytoone division attribute (and its foreign key column named query_number) to be pluggable = false and updatable = false

// Employee.java

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    @JoinColumn(name="DIVISION_CODE",referencedColumnName="DIVISION_CODE"),@JoinColumn(name="SURVEY_NUMBER",referencedColumnName="SURVEY_NUMBER",updatable=false)})
private Division division;

4 º when you have composite foreign keys, we cannot mix pluggable or non updatable – non updatable

It's like

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    // I can be updatable
    @JoinColumn(name="DIVISION_CODE",insertable=false),// And i can be insertable
    @JoinColumn(name="SURVEY_NUMBER",updatable=false)})
private Division division;

Otherwise, hibernate will complain

Therefore, it is called division_ The composite foreign key column of code should also be marked with insertable = false and updatable = false to avoid the above exceptions

// Employee.java

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    @JoinColumn(name="DIVISION_CODE",updatable=false)})
private Division division;

Because we can't update Division_ Code column, our division property behaves like a constant Then, you can imagine creating a new attribute called divisioncode to change the division_ The code column, as shown below

// Employee.java

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    @JoinColumn(name="DIVISION_CODE",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;

Well, let's have a look Suppose we have the following division table

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

Remember: there is a foreign key constraint between division and employee

Did you think of it

You execute the following code

employee. setDivisionCode(7);

Wow, see division above_ TABLE. DIVISION_ Are some values in the code column equal to 7?

The answer is clear: no (you will see constraint violations)

So, this is an inconsistent mapping Hibernate does not allow

to greet,

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>