当子级具有复合键时如何级联插入子级实体

时间:2019-10-30 17:19:49

标签: java hibernate jpa

我从EF的JPA开始,尝试在孩子有复合钥匙的地方做一个简单的主从细节插入。

可以正确插入foo(没有错误,Hibernate只是将插入内容打印到Foo语句中),但是该栏却被忽略了。 我发现this question在键中定义了关系,但是我也无法使它起作用(与我的原始解决方案相同的问题,没有例外,也没有子插入)。

我的代码当前如下所示:

// pre processors
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

// structs & enums
enum status {UNDERGRADUATE, GRADUATE};
struct student
{
    string fullNAme;
    int* scores;
    status stStatus;
    int avg;
    int* max;
};

// function prototypes

void menu(student[], int, int);
void outputA_Struct(student, int); // full name and average
void changeScore(student*, string, int, int, int, int);
void outputVector(vector<student>);
int minScore(int*, int);
int* maxScore(int*, int);
int computeAvg(int*, int);
vector<student> listOfHigherThan_X(student*, int, int);
vector<student> listOfAll_As(student*, int, int);




int main()
{
    // variables
    string fileName;
    string first;
    string last;
    int numStudents;
    int numScores;
    fstream inputFile;
    student* gradeBook;

    // get the information from the user
    cout << "What is the name of the file you would like to use?" << endl;
    cin >> fileName;
    cout << "How many students will there be?" << endl;
    cin >> numStudents;
    cout << "How many scores are there with each student?" << endl;

    // open the file
    inputFile.open(fileName, ios::in);

    // make a new array of the students
    gradeBook = new student[numStudents];

    // fill in the information for the array
    for(int i =0; i < numStudents; i++)
    {
        // name
        inputFile >> first >> last;
        gradeBook[i].fullNAme = first + " " + last;
        // status
        inputFile >> gradeBook[i].stStatus;// error on >>
        // grades
        for (int j = 0; j < numScores; j++)
        {
            inputFile >> gradeBook[i].scores[j];
            gradeBook[i].avg += gradeBook[i].scores[j];
        }
        // average
        computeAvg(gradeBook[i].scores, numScores);
    }
    inputFile.close();

    // run the menu
    while (true)
    {
        menu(gradeBook, numStudents, numScores);// error on gradebook
    }
}

如果这有什么区别,我正在将JPA 2.2与Hibernate 5.4结合使用。

为了更好地阐明我的追求(对于每个懂一点EF的人来说):

@Entity
public class Foo {
    @Id
    private String fooID;

    @OneToMany(mappedBy = "foo")
    private List<Bar> bars = new ArrayList<>();

    // getter, setter,...
}

@Entity
public class Bar {

    @EmbeddedId
    private BarId id;

    public Bar(){
        this.id = new BarId();
    }

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @MapsId("fooID")
    @JoinColumn(name = "fooID", referencedColumnName = "fooID")
    private Foo foo;

    public void setFooId(String fooId){
        this.id.setFooId(fooId);
    }

    public void setBarNo(int barNo){
        this.id.setBarNo(barNo);
    }

    // other getter, setter,...
}

@Embeddable
public class BarId implements Serializable {
    private String fooID;
    private int barNo;

    // getter, setter, hashCode, equals,...
}

// ...
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();

Foo newFoo = new Foo();
newFoo.setFooID("baz");

Bar newBar = new Bar();
newBar.setFooId(newFoo.getFooId()); // even necessary?
newBar.setBarNo(1);
newBar.setFoo(newFoo);

newFoo.getBars().add(newBar);

em.persist(newFoo);
em.getTransaction().commit();

要使它正常工作,我需要更改什么? 还是从一开始我就完全错误地使用JPA?

1 个答案:

答案 0 :(得分:0)

弄清楚了:cascade = CascadeType.PERSIST必须放在关系的主端而不是细节侧,例如:

@OneToMany(mappedBy = "foo", cascade = CascadeType.PERSIST)
private List<Bar> bars = new ArrayList<>();