Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Hibernate作为持久性保存对象,并使用Jackson保存外键?_Java_Spring_Hibernate_Jackson - Fatal编程技术网

Java 如何使用Hibernate作为持久性保存对象,并使用Jackson保存外键?

Java 如何使用Hibernate作为持久性保存对象,并使用Jackson保存外键?,java,spring,hibernate,jackson,Java,Spring,Hibernate,Jackson,如果这个问题以前被回答过,我想提前道歉 请注意,该项目使用SpringBoot、Jackson和Hibernate 不管怎么说,我把一个项目交给了他。我想知道他是如何在Jasenko的项目中保存一个对象的,产品对象。在本项目中,Product对象如下所示。请注意,我删除了部分代码以关注外键: @JoinColumn(name = "member_id") @NotNull private Long member_id; 我可以使用以下JSON保存新记录: { "name" : "Produ

如果这个问题以前被回答过,我想提前道歉

请注意,该项目使用SpringBoot、Jackson和Hibernate

不管怎么说,我把一个项目交给了他。我想知道他是如何在Jasenko的项目中保存一个对象的,产品对象。在本项目中,Product对象如下所示。请注意,我删除了部分代码以关注外键:

@JoinColumn(name = "member_id")
@NotNull
private Long member_id;
我可以使用以下JSON保存新记录:

{
  "name" : "Product 2",
  "member_id" : "1"
}
[
    {
        "id": 1,
        "name": "Derp",
        "currency": "599",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    },
    {
        "id": 2,
        "name": "Another product ",
       "currency": "909",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    },
    {
        "id": 3,
        "name": "Another product 1",
        "currency": "909",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    }
]
这是可行的,但从我在互联网上搜索到的情况来看,最好使用这个:

public class Product {

@ManyToOne()
@JoinColumn(name="member_id")
private Member member;

/* A getter/setter for the memeber id*/
public Long getMember_id() {
    return this.member.getId();
}

public void setMember_id(Long member_id) {
    this.member.setId(member_id);
}
}
我试图用上面相同的json保存一条新记录,但出现以下错误:

java.lang.NullPointerException: null
at com.jersey.representations.Product.setMember_id(Product.java:100)
这里有一个指向my的链接,其中包含修改过的代码

我还检查了这一点,这与我的担忧类似。但它首先做的是发送一个select查询来填充成员对象。但这意味着在保存记录之前,我必须请求另一个select语句。这有点贵,不是吗

更新 我在构造函数中添加了以下代码:

public Product() {
    this.member = new Member();
}
我确实解决了我的问题,但这是处理我的问题的正确方法吗

更新2

我试图避免发送以下JSON:

{
  "name" : "Product 2",
  "member_id" : "1"
}
[
    {
        "id": 1,
        "name": "Derp",
        "currency": "599",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    },
    {
        "id": 2,
        "name": "Another product ",
       "currency": "909",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    },
    {
        "id": 3,
        "name": "Another product 1",
        "currency": "909",
        "regularPrice": 1203,
        "discountPrice": 59,
        "member": {
            "id": 1,
            "firstName": "Paul",
            "lastName": "Andrews",
            "email": "myemail@email.com"
        }
    }
]
如您所见,该成员不断重复,而我只能发送memberId


请尝试使用带有模型和产品持久性的简单控制台应用程序学习Hibernate。产品不需要@JoinColumn,但需要@OneToMany和mappedBy属性。您可以将其称为成员和产品的类似物。在每个产品中,您都需要有外键才能使用户将产品添加到成员。对于实验,您可以使用或

好的,所以我终于开始工作了。我不知道该指出哪里,但我可以肯定地说,这不是杰克逊的JSON编组问题

以下是我的解决方案:

首先,我找不到解决方案,只能将其添加到具有外键的类中:

@Entity
public class Product {
    public Product() {
        this.member = new Member();
    }

    @ManyToOne()
    @JoinColumn(name="blargh")
    private Member member;
    /** Jackson can't instantiate and object automatically so you have to help it **/
    /** By creating the object right after Product is initialzed by some other code **/
    public Long getMobileNum() {
        return this.member.getMobileNum();
    }

    public void setMobileNum(Long mobileNum) {
        this.member.setMobileNum(mobileNum);
    }
}
下一步是在另一个类中查找Id注释

@Entity
public class Member {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Id
    private Long mobileNum;
}
为了证明这一点,我故意把注释弄错了。在Product类中,将其链接到成员类的外键是mobileNum。如果mobileNum或任何外键都带有@Id注释,Hibernate将正确绑定它,并且在保存对象时不会出现任何问题

但是如果外键没有用@Id注释,Hibernate即使Jackson已经将JSON正确地映射到对象,它也不会正确地绑定它,从而导致空值。Google搜索关键字:对象引用未保存的临时实例

在我看来,添加级联不是一个好的解决方案,因为它只会在成员类中创建更多记录。即使记录已经存在,它也会继续创建!正在尝试对mobileNum设置唯一约束并删除@Id注释


总的来说,这周的冬眠真的让我筋疲力尽。如果您是一名在优化现有SQL方面有经验的开发人员,并且只想将其转换为代码,那么请远离Hibernate。使用MyBatis,即使它有很多样板文件,手动创建SQL也比使用Hibernate更令人满意。

您可能有NPE,因为您试图设置成员id值的成员字段未初始化。首先,您必须创建成员,然后为其分配id。但是,如果该成员已经存在,该怎么办?这不会创建另一个成员记录吗?所以你必须找出它是否已经存在。我认为你这样做是错误的。为什么要使用为Product类中的成员设置id的方法?在Product类中,您应该设置整个成员对象,或者您应该有Long memberId字段,并将您的Member_id值设置为此字段。我将更新我的问题以回答您的问题。更好的方法是,如果不存在新成员,则创建新成员,或者从数据库中分配现有成员,如dao.findMemberByIdmemberId;好啊我要去看看这个。我得再检查一下我的工作。我被这件事烧坏了,忘了为什么要放弃它。@FrancisZabala你可以把你的作品流出来。那会很有趣的。我的小溪。@FrancisZabala是的: