简体   繁体   中英

JPA (Hibernate) mapping of Map. What annotations should I use for java.util.Map mapping?

Tables structure:

TABLE products (id (PK), name, price);

TABLE orders (id (PK), customer_id, user_id);

//product_quantity is quantity of product in particular order
TABLE products_to_orders (product_id, order_id, product_quantity
  PRIMARY KEY (product_id, order_id),
  FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE,
  FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE
);

Here is my Order.java :

@Entity
@Table(name = "orders")
public class Order extends BaseEntity {
...
//this map holds Products and their quantities in order;
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(
                name = "products_to_orders"
                ,joinColumns = @JoinColumn(name = "order_id")
                ,inverseJoinColumns = @JoinColumn(name = "product_id") //it seems that i don't need this line
        )
        @MapKeyJoinColumn(name = "product_id")
        @Column(name = "product_quantity")
        private Map<Product, Integer> productQuantityMap;
...

My mapping using those annotations doesn't work. It gives an exception:

Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.malikov.shopsystem.model.Order.productQuantityMap[java.lang.Integer]

So I am not able to manage how to properly annotate this Map. I would appreciate your help a lot! Here is link to my repsitory on GitHub https://github.com/malikov-yurii/online-shop-management-system.git

UPDATE. There are two right solutions (from Neil and Maciej):

  Variation 1:
    @ElementCollection(fetch = FetchType.EAGER)
    @JoinTable(
            name = "products_to_orders"
            ,joinColumns = @JoinColumn(name = "order_id")
    )
    @MapKeyJoinColumn(name = "product_id")
    @Column(name = "product_quantity")
    private Map<Product, Integer> productQuantityMap;

  Variation 2
    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "products_to_orders")
    @MapKeyJoinColumn(name = "product_id")
    @Column(name = "product_quantity")
    private Map<Product, Integer> productQuantityMap;

Doesn't the documentation for your chosen JPA provider include how to map your Map field? You can see it described in this documentation provided by DataNucleus JPA. In simple terms you need to include

@ElementCollection
@JoinTable
Map<Product, Integer> productQuantityMap;

(as well as any additional annotations if you want to configure the schema, but these are the essential bits).

Try this configuration. @ElementCollection instead of @ManyToMany and @CollectionTable instead of @JoinTable

@ElementCollection
@CollectionTable(name = "products_to_orders"        
@MapKeyJoinColumn(name = "product_id")
@Column(name = "product_quantity")
private Map<Product, Integer> productQuantityMap;

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