Spring JPA Hibernate 重复数据问题

3

你好,我是个新手。 我正在使用spring jpa hibernate制作自己的应用程序。 我有一个实体类,它通常可以工作,但是会出现属性重复的问题。 我的代码看起来像这样:

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;

    @Entity
    public class Event {

        @Id
        @GeneratedValue
        private Integer id;

        public Integer getId() {
            return id;
        }

        @Column(nullable = false)
        public void setId(Integer id) {
            this.id = id;
        }

        /*------------------------------ title ------------------------*/
        private String title;
        @Column(nullable = false)
        public String getTitle() {
            return title;
        }

        @Column(nullable = false)
        public void setTitle(String title) {
            this.title = title;
        }

        /* [Note] I have two extra ids : event_id, eventId 
        - so these are not the case of the duplication. */
        /*------------------- event_id -----------------------------*/
        private String event_id;

        public String getEvent_id() {
            return event_id;
        }

        public void setEvent_id(String event_id) {
            this.event_id = event_id;
        }

    /*-------------- eventId -------------------------------------*/
        @Column(unique = true)
        private String eventId;

        public String getEventId() {
            return eventId;
        }

        public void setEventId(String eventId) {
            this.eventId = eventId;
        }



        /*------------------------------ publishedDate ------------------------------------------*/
        private String publishedDate;   

        public String getPublishedDate() {
            return publishedDate;
        }

        @Column(nullable = false)
        public void setPublishedDate(String publishedDate) {
            this.publishedDate = publishedDate;
        }


        /*--------------------------------- endTime -----------------------------------*/
        private String endTime;         
        public String getEndTime() {
            return endTime;
        }
        @Column(nullable = false)
        public void setEndTime(String endTime) {
            this.endTime = endTime;
        }

        /*-------------------------------- user ------------------------------------------*/
        @ManyToOne
        @JoinColumn(name="user_id")   
        private User user;
        public User getUser() {
            return user;
        }
        @Column(nullable = false)
        public void setUser(User user) {
            this.user = user;

    }

当我查看JPA图表时,发现有多个属性重复出现。我在下面添加了我的JPA图像(红色部分为重复项):

enter image description here

这是我第一次使用Java编程开发应用程序,请谅解。即使我已经阅读了Spring JPA的文档,也很难找出代码中到底哪里出错了。您有什么想法吗?提前感谢。


2
要么注释字段,要么注释其中一个getter/setter。你已经同时注释了getter和setter。此外,在JPA中不允许组合字段级别注释和方法注释,请使用字段或方法,不要混合使用。我建议使用字段级别注释。 - M. Deinum
谢谢你的回答。我已经检查了getter和setter,似乎不是因为这个原因。但我不明白什么是“使用字段级别注释”。你能详细解释一下吗? - user1915570
是的,这是因为您在类中的getter和字段上都放置了注释。 - M. Deinum
那么,你的意思是这些 @Column(nullable = false) public String getTitle() { return title; }。这是否意味着“在getter方法上放置注解”?所以我应该删除所有getxxx、setxxxx上的@Column...吗? - user1915570
请看我的回答。你应该在字段上或者在getter(或setter)上使用注解,而不是两者都用。 - M. Deinum
@user1915570 是的,只需使用其中一个(field 或 setter),请看我的答案。 - cнŝdk
3个回答

2
问题在于JPA希望使用字段级别的注释或访问器(getter/setter)注释。然而,您同时使用了两者,这基本上是不允许的。请从访问器中删除所有注释,仅将它们放在字段上。
Java编程(样式)的小提示:将字段放在类的顶部而不是访问器之间。
@Entity
public class Event {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(unique = true)
    private String eventId;

    private String event_id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String publishedDate;   

    @Column(nullable = false)
    private String endTime;         

    @ManyToOne
    @JoinColumn(name="user_id")   
    @Column(nullable = false)
    private User user;

    // Getters / Setters omitted

}

移除访问器中的注释,你真的想设置id吗?我认为不需要,所以您可能需要删除setId方法。


谢谢您的回答。是的,它解决了重复问题。我在所有地方使用注释(nullable = false)的原因是因为当我的应用程序初始化时,它会创建一个空实体。我不知道为什么。这可能与“设置ID”有关吗? - user1915570

1

如评论中所提到的,您的问题在于您为同一属性使用了两个注释,一个在字段中,另一个在其getter/setter方法中,因此您只需要使用其中之一,例如:

    @Id
    @GeneratedValue
    private Integer id;

    public Integer getId() {
        return id;
    }

    @Column(nullable = false)
    public void setId(Integer id) {
        this.id = id;
    }

应该是:

    @Id
    @GeneratedValue
    private Integer id;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

在这里同时使用getter和setter是错误的:

    @Column(nullable = false)
    public String getTitle() {
        return title;
    }

    @Column(nullable = false)
    public void setTitle(String title) {
        this.title = title;
    }

注意:
为了避免这种情况,您必须在以下两者之间进行选择:
- 使用字段的注释。 - 或者使用其setter的注释。

谢谢你的回答。由于我不能接受多个答案,我也投了你的答案。再次感谢。 - user1915570
太好了,很高兴能帮到你。 - cнŝdk

0

Spring Boot 2.0.0.M5,JPA,Hibernate 5.2.11.Final

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")
@SequenceGenerator(name = "auto_gen", sequenceName = "customer_id_seq", allocationSize=1)
@Column(name = "id")
private Long id;

这是一个工作样例:

package hello;

import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")
    @SequenceGenerator(name = "auto_gen", sequenceName = "customer_id_seq", allocationSize = 1)
    @Column(name = "id")
    private Long id;

    @Column(name = "first_name")
    //@Type(type="org.hibernate.type.StringType")
    private String firstName;

    @Column(name = "last_name")
    //@Type(type="org.hibernate.type.StringType")
    private String lastName;

    protected Customer() {

    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接