代码之家  ›  专栏  ›  技术社区  ›  Arthur Ronald

堆栈溢出映射(Hibernate)

  •  3
  • Arthur Ronald  · 技术社区  · 16 年前

    @Entity
    public class User {
    
        private Integer id
    
        private List<Info> infoList;    
    
        @Id
        public getId() {
            return this.id;
        }
    
        @OneToMany(cascade=CascadeType.ALL)
        @JoinColumn(name="USER_ID", insertable=false, updateable=false, nullable=false)
        public getInfoList() {
            return this.infoList;
        }
    
        public void addQuestion(Info question) {
            info.setInfoCategory(InfoCategory.QUESTION);
            info.setInfoId(new InfoId(getId(), getInfoList().size()));
    
            getInfoList().add(question);
        }
    
        public void addAnswer(InfoRepository repository, Integer questionIndex, Info answer) {
            Info question = repository.getInfoById(new InfoId(getId(), questionIndex));
    
            if(question.getInfoCategory().equals(InfoCategory.ANSWER))
                throw new RuntimeException("Is not a question");
    
            if(question.getAnswer() != null)
                throw new RuntimeException("You can not post a new answer");
    
            answer.setInfoCategory(InfoCategory.ANSWER);
            answer.setInfoId(new InfoId(getId(), getInfoList().size()));
    
            getInfoList().add(answer);
    
            question.setAnswer(answer);
        }
    
    }
    

    @Entity
    public class Info implements Serializable {
    
        private InfoId infoId;
    
        private Info answer;
    
        private InfoCategory infoCategory;
    
        public Info() {}
    
        @Embeddable
        public static class InfoId {
    
            private Integer userId;
            private Integer index;
    
            public InfoId(Integer userId, Integer index) {
                this.userId = userId;
                this.index = index;
            }
    
            @Column("USER_ID", updateable=false, nullable=false)
            public getUserId() {
                return this.userId;
            } 
    
            @Column("INFO_INDEX", updateable=false, nullable=false)
            public getIndex() {
                return this.index;
            }
    
            // equals and hashcode
    
        }
    
        // mapped as a ManyToOne instead of @OneToOne
        @ManyToOne
        JoinColumns({
            JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
            JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
        })
        public Info getAnswer() {
            return this.answer;  
        }
    
        @EmbeddedId
        public InfoId getInfoId() {
            return this.infoId;
        }
    
    }
    

    在getAnswer中,我使用ManyToOne而不是OneToOne,因为一些问题与OneToOne映射有关。OneToOne可以映射为ManyToOne(@JoinColumn中的unique=true)。INFO_INDEX与任何特定目的无关。在LEGACY系统中,只需一个密钥即可支持复合主键。

    在回答之前,请注意以下事项:

    如果一个对象有一个分配的标识符或复合键,则应在调用save()之前将标识符分配给对象实例

    在getAnswer中,因为Hibernate不允许两个可变属性共享同一个库(userId也使用USER_ID),否则我将在响应中获取USER_ID。属性必须映射为insertable=false,updateable=false

    @ManyToOne
    JoinColumns({
        JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
        JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
    })
    

    小心,这是一个合法的系统。

    当做,

    2 回复  |  直到 16 年前
        1
  •  2
  •   ChssPly76    16 年前

    大幅度地

    InfoId.index 出于某种目的(排序问题/答案?您可以在 list 映射),将其作为常规属性保存。

    UserId ManyToOne User @OneToMany(mappedBy="User")

    ?不是吗 OneToMany Question Answer

        2
  •  1
  •   Akhil Jain Thedaego    13 年前

    @ManyToOne
    JoinColumns({
        JoinColumn(name="USER_ID", referencedColumnName="USER_ID", insertable=false, updateable=false),
        JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false)
    })
    

    Hibernate会抱怨,因为它不允许混合不同的可插入和可更新。请注意,USER_ID JoinColumn中有一个可插入和可更新的,并且只能插入ANSWER_INDEX JoinColumn中。

    JoinColumn(name="ANSWER_INDEX", referencedColumnName="INFO_INDEX", insertable=false, updateable=false)
    

    这样,Hibernate就不会抱怨了。

    我设置了一个名为answerIndex的新属性

    private Integer answerIndex;   
    
    @Column(name="ANSWER_INDEX", insertable=false)
    public void getAnswerIndex() {
        return this.answerIndex;
    }
    

    然后在用户addAnswer中

    public void addAnswer(InfoRepository repository, Integer questionIndex, Info answer) {
        Info question = repository.getInfoById(new InfoId(getId(), questionIndex));
    
        if(question.getInfoCategory().equals(InfoCategory.ANSWER))
            throw new RuntimeException("Is not a question");
    
        if(question.getAnswer() != null)
            throw new RuntimeException("You can not post a new answer");
    
        answer.setInfoCategory(InfoCategory.ANSWER);
        answer.setInfoId(new InfoId(getId(), getInfoList().size()));
    
        getInfoList().add(answer);
    
        // Added in order to set up AnswerIndex property
        question.setAnswerIndex(answer.getInfoId().getIndex());
    }