Search code examples
javahibernatejpaenumsmany-to-many

JPA enumerated entity with ManyToMany relationship


I have two entities with many-to-many relationship. My database structure:

Document    Status                  Document_Status
╔════╗      ╔════╦══════════╗       ╔═════════════╦═══════════╗
║ id ║      ║ id ║  status  ║       ║ document_id ║ status_id ║
╠════╣      ╠════╬══════════╣       ╠═════════════╬═══════════╣
║  1 ║      ║  1 ║ STORED   ║       ║           1 ║         1 ║
║  2 ║      ║  2 ║ APPROVED ║       ║           2 ║         1 ║
║  3 ║      ╚════╩══════════╝       ║           3 ║         2 ║
╚════╝                              ╚═════════════╩═══════════╝

And I want to use enum for Status.

public enum Status {
    STORED, APPROVED
}

@Entity
public class Document {

    @Id
    @GeneratedValue
    private long id;

    // ??
    private Set<Status> statuses;
}

I've tried to implement it this way, but the solution ignores Status table and tries to create statuses from status_id in EnumType.ORDINAL way:

@ElementCollection(targetClass = Status.class)
@CollectionTable(name = "Document_Status", joinColumns = @JoinColumn(name = "document_id"))
@Column(name = "status_id", nullable = false)
private Set<Status> statuses;

@Enumerated(EnumType.STRING) also doesn't help. It starts to find value with name "1" in Status enum.

I could wrap the enum into entity like recommended here. But isn't it possible to be implemented without creation of wrapper entity?


Solution

  • I think you should edit your Entities to be like that

    Status

    @Entity
    public class Status {
    
        public enum StatusEnum {
            STORED, APPROVED
        }
    
        @Id
        @GeneratedValue
        private Integer id;
    
        @Enumerated(EnumType.STRING)
        @Column(name = "status")
        private StatusEnum status;
    }
    

    Document

    @Entity
    public class Document {
    
        @Id
        @GeneratedValue
        private long id;
    
        @ManyToMany
        private Set<Status> statuses;
    }