简体   繁体   中英

design spring data jpa annotated class with 2 foreign keys

So for an exercise I am build an Java web app using Spring. It is a simple lottery API.

I decided to use spring data JPA in this project and I am quite a newbie in ORM based database access.
I am also using flyway for data versioning. So I generate db using flyway scripts and then validate it against my spring data jpa models.

It is quite complicated... but in the end I think it offers more than it complicates stuff.

So I have 3 tables

RAFFLE
raffleID - primmary key
startDate
endDate
winningNumbers

TICKETS
ticketID - primmary key
raffleID - foreign key
customerName
numbers

WINNERS
ticketID - foreignKey
raffleID - foreignKey
Amount
Type

Is this bad design? Should I also use primmary key for for WINNERS table? Would it be possible to create PFK ? I am using MariaDB as a database.

My spring code so far:

@Entity
@Data
@Table(name = "Raffle")
public class Raffle{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long raffleID;

    private Timestamp startDate;
    private Timestamp endDate;
    private String winningNumbers;

    @OneToMany(mappedBy = "Tickets")
    private Set<Tickets> tickets;

    public Raffle(Timestamp startDate, Timestamp endDate, String winningNumbers,  Tickets... ticket){
        this.startDate = startDate;
        this.endDate = endDate;
        this.winningNumbers = winningNumbers;
    }
}

@Entity
@Data
@Table(name = "Tickets")
public class Tickets {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long TicketID;

    @ManyToOne
    @JoinColumn(name="RAFFLE_ID")
    private Raffle RaffleID;

    private String customerName;
    private String numbers;

}

@Entity
@Data
@Table(name = "Winners")
public class Winners {

    @Id
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "raffleID", referencedColumnName = "raffleID")
    private Raffle raffle;

    @Id
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ticketID", referencedColumnName = "ticketID")
    private Tickets ticket;

    private Double prizeWon;
    private String prizeType;
    private String status;
}

Currently I am getting thrown this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.grmkris.lightningloterry.model.database.Tickets.Tickets in com.grmkris.lightningloterry.model.database.Raffle.tickets

I know I should educate myself more on JPA mechanics... but so far with googling I haven't found exact same problem I am facing. So I will also appreciate any resource you can recommend me on this topic!

Kinds regards

EDIT: just after posting this, I found this question: 2 Foreign Keys Into a New Table from Different Entities Hibernate It advises to use association table . Is there any simpler way of doing this?

I decided to turn off flyway for now and just use spring data jpa. I managed to fix all the problems. Now table with 2 foreign keys works. I use @OneToOne annotiation because 1 ticket can we winnable only once. But used @ManyToOne with Raffle because there can be multiple winners in the raffle. Please correct me if I am wrong.
I'd still like to be able to use flyway but hibernate generates its own classes which are quite hard to replicate using sql by hand.

@Entity 
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Raffle{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long raffleID;

    private Timestamp startDate;
    private Timestamp endDate;
    private String winningNumbers;

    @OneToMany(mappedBy = "raffle")
    private Set<Tickets> tickets;

    @OneToMany(mappedBy="raffle")
    private Set<Winners> winner;
}

@Entity
@Data
@Builder
@Table(name = "Tickets")
public class Tickets {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long ticketID;

    @ManyToOne
    @JoinColumn(name="raffleID", nullable=false)
    private Raffle raffle;

    private String customerName;
    private String customerEmail;
    private String customerDescription;
    private Integer[] numbers;
    private String status;

    @OneToMany(mappedBy="ticket")
    private Set<Winners> winner;

}


@Entity
@Data
@Table(name = "Winners")
public class Winners {

    @EmbeddedId private WinnersID id;

    @ManyToOne @MapsId("raffleID")
    private Raffle raffle;

    @OneToOne @MapsId("ticketID")
    private Tickets ticket;

    private Double prizeWon;
    private String prizeType;
    private String status;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM