J'ai une classe @Entity, avec une annotation @Id et une annotation @OneToOne sur le même champ. Cela ne poserait généralement pas de problème, mais la classe d'entité du champ avec ces annotations utilise une clé composite. Cela cause plus de complications que prévu.

Voici la classe d'entité qui pose problème :

@Entity
public class ReportDetails implements Serializable {

    @Id
    @OneToOne
    private MachineLine machineLine;
}

Et voici la classe d'entité MachineLine qui est utilisée comme ID dans ReportDetails :

@Entity
@IdClass(MachineLine.MachineLineKey.class)
public class MachineLine {

    @Id
    @ManyToOne
    private Machine machine;

    @Id
    private long lineIndex;

    public static class MachineLineKey implements Serializable {
        private Machine machine;
        private long lineIndex;
    }
}

J'ai omis tous les champs supplémentaires et les getters et setters de ces définitions de classe, pour économiser de l'espace.

Lorsque j'essaie d'exécuter mon application, l'exception suivante s'affiche :

java.lang.IllegalArgumentException: This class [class ReportDetails] does not define an IdClass

Lorsque je mets une annotation @IdClass sur ReportDetails, il faut ensuite définir les champs individuels de la classe que je définis dans @IdClass, comme dans MachineLine. Cependant, j'essaie d'éviter de le faire, en faveur du retour de l'intégralité de l'entité MachineLine chaque fois qu'une entité ReportDetails est extraite de la base de données.

Existe-t-il un moyen d'avoir MachineLine comme champ ID de ReportDetails, sans avoir à définir des champs supplémentaires dans ReportDetails ?

0
Rafe 3 févr. 2020 à 18:41

1 réponse

Meilleure réponse

C'est ce que JPA appelle une « identité dérivée ». Vous pouvez essayer quelque chose comme ceci :

Détails du rapport :

@Entity
public class ReportDetails implements Serializable {
    // all attributes map by the relationship: AttributeOverride is not allowed
    @EmbeddedId
    private MachineLine.Id id;

    @MapsId
    @JoinColumns({
        @JoinColumn(name="machineId", referencedColumnName="machineId"),
        @JoinColumn(name="machineLineIndex", referencedColumnName="index")
    })
    @OneToOne
    private MachineLine machineLine;

    // ...
}

Ligne de machines :

@Entity
public class MachineLine {

    @EmbeddedId
    private Id id;

    @MapsId("machineId") // maps machineId attribute of embedded id
    @ManyToOne
    private Machine machine;

    // ...

    @Embeddable
    public static class Id implements Serializable {
        private long machineId; // corresponds to PK type of Machine
        private long index;
        // ...
    }
}

Machine:

@Entity
public class Machine {

    @Id
    private long id;

    @OneToMany(mappedBy = "machine")
    private List<MachineLine> lines;

    // ...
}

Les identités dérivées sont traitées (avec des exemples) dans le JPA 2.2 spec dans la section 2.4.1.

1
Brian Vosburgh 4 févr. 2020 à 04:42