【问题标题】:How can I find an object in JPA by its Composited Key ID如何通过复合键 ID 在 JPA 中找到对象
【发布时间】:2021-08-06 04:00:02
【问题描述】:

我试图从我的数据库表 Real_States 中找到一个对象,如下所示:

CREATE TABLE REAL_STATES (
address VARCHAR(30) NOT NULL,
admin_id VARCHAR(15) NOT NULL,
resident_id VARCHAR(15),
real_state_type_id INT(6) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (address, block, internal_id),
FOREIGN KEY (real_state_type_id) REFERENCES REAL_STATE_TYPES (real_state_type_id),
FOREIGN KEY (admin_id) REFERENCES ADMINS (admin_id),
FOREIGN KEY (resident_id) REFERENCES RESIDENTS (resident_id)
);

我想通过它的复合主键(地址、块、internal_id)获取该表的一行,所有这些都来自我的 EntityManager。是这样的:

public RealState findRealState(RealStateID realStateId) {
    RealState realState = em.find(RealState.class, realStateId); // first Try, which failed
    List<RealState> realStates = em.createQuery("FROM RealState rs WHERE  rs.realStateID.address like :" + realStateId.getAddress()).getResultList(); // second try which failed too
    for (RealState realState2 : realStates) {
        System.out.println(realState2.toString());
    }
    if (realState == null) {
        throw new EntityNotFoundException("Can't find realState for ID " + realStateId.toString());
    }
    return realState;
}

RealStateID 类声明如下:

@Embeddable
public class RealStateID  implements Serializable{
    private static final long serialVersionUID = 6485406412363395170L;
    @Column(name = "address")
    private String address;
    @Column(name = "block")
    private String block;
    @Column(name = "internal_id")
    private int internal_id;
    //getters..setters..

但是我只是错误地出错,IDK 我做错了什么,我想弄清楚它。我没有使用 Spring,只使用 JPA Hibernate 和 Java。

【问题讨论】:

    标签: java hibernate jpa hql composite-key


    【解决方案1】:

    正如documentation 中所述:

    主键类必须定义 equalshashCode 方法,与主键映射到的基础数据库类型的相等性一致。

    假设它的方法:

    RealState realState = em.find(RealState.class, new RealStateID(...));
    

    应该按预期工作。

    编辑您的RealStateID 应如下所示:

    @Embeddable
    public class RealStateID  implements Serializable{
        private static final long serialVersionUID = 6485406412363395170L;
    
        @Column(name = "address")
        private String address;
    
        @Column(name = "block")
        private String block;
    
        @Column(name = "internal_id")
        private int internal_id;`
        
        // getters, setters
    
        @Override
        public boolean equals(Object o) {
            if ( this == o ) return true;
            if ( o == null || getClass() != o.getClass() ) return false;
    
            RealStateID pk = (RealStateID) o;
            return Objects.equals(address, pk.address) &&
                    Objects.equals(block, pk.block) &&
                    Objects.equals(internal_id, pk.internal_id);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(address, block, internal_id);
        }
    }
    

    【讨论】:

    • 我刚刚运行,当我用“A302”、“A1”和“302”填充 jsp 值时,它给了我下一个错误:javax.persistence.EntityNotFoundException Can't find realState for ID RealStateID [address=A302, block=A1, internal_id=302] 这不可能,因为我在 BD 的表 Real_States 中有该行
    • 请展示你的RealStateID类的完整实现
    • 如你所问,我已经用 RealStateID 的实现编辑了问题
    • 您的RealStateID 班级是否像我更新的答案一样定义了equalshashCode
    • 不,它没有它们,但现在错误已更改为 Exception handling request to /ProyectoSw/FindRealStateServlet: java.lang.NoSuchMethodError: edu.uptc.model.Manager.findRealState(Ljava/lang /String;)Ledu/uptc/entity/RealState;
    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 2021-09-04
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    相关资源
    最近更新 更多