Reputation: 1454
I'm having situation where I have multiple entities (Users, Products, Categories) where each of have one or more Images. I want to use only one Image table to persist the info about the images.
I like to achieve something like this with JPA (Hibernate):
id foreign_key image_type file_path
1 1 PROFILE_USER /file/….
2 2 PROFILE_USER /file/….
3 3 CATEGORY_IMAGE /file/….
4 4 CATEGORY_IMAGE /file/….
5 1 PRODUCT_IMAGE /file/….
Where foreign_key is the primary id key for the different entity types ( Users, Categories, Products etc..) The combination of foreign_key and image_type indicates for the specific entity ( PROFILE_USERS(Users), PRODUCT_IMAGE(Products), CATEGORY_IMAGE(Category) etc..
I want to do this because, it it not cool to have separate image table for the different cases ( Users - > users_images, Products -> product_images, Category -> category_images)
Upvotes: 1
Views: 1895
Reputation: 1454
Maybe I was not able to explain it correctly. I managed to do it as I wanted with @Where annotation on each ProductImage, UserImage etc.. Let me explain it.
@Getter
@Setter
@Entity
@Table(name = "products")
@EntityListeners(AuditingEntityListener.class)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@OrderBy("id")
@JoinColumn(name = "image_type_id")
@OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.EAGER, targetEntity = ProductImage.class)
private Set<ProductImage> images = new LinkedHashSet<>();
}
--
@Table(name = "images")
@EntityListeners(AuditingEntityListener.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="image_type",
discriminatorType = DiscriminatorType.STRING)
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "original_file_name")
private String originalFileName;
@Column(name = "file_name")
private String fileName;
@Column(name = "file_path")
private String filePath;
@Column(name = "file_size")
private Long fileSize;
@Column(name = "thumbnail_path")
private String thumbnailPath;
}
--
@Entity
@DiscriminatorValue("PRODUCT_IMAGE")
@Where(clause = "image_type = \"PRODUCT_IMAGE\"")
public class ProductImage extends Image {
}
Now we have one Image table which is distinguished by each implementation (ProductImages, UserImages etc) only by DiscriminatorColumn and image_type_id combination of each defines one specific instance from Product ( and his ProductImages). When the products and his images are query, my select statement is like this - "where ( images0_.image_type = "PRODUCT_IMAGE") and images0_.image_type_id=? order by images0_.id"
There is no need of JoinTable which should contain the relation for image id and product id, in order to distinguishes the images for specific product instance.
@Chris does this make sense for you? Can you find some Pros and Cons for this approach ?
Upvotes: 1