I have entity Order. It contains a list of glass parts and a list of non-glass parts. Part is a single entity with attribute PartType (glass/non-glass). Is this please doable with Spring Data? How? I'm using Spring Boot 1.3.1.RELEASE with Hibernate.
@Entity
@Table(name="order")
public class Order {
...
@OneToMany(...)
private List<Part> glassParts;
@OneToMany(...)
private List<Part> otherParts;
}
@Entity
@Table(name="part")
public class Part {
...
@Column(...)
private PartType partType;
@Column(...)
private String code;
@Column(...)
private String description;
}
I believe that in you case it is not a good idea to create two lists. To achive the result there are two common approaches. The first one is to create a bi-directional relation and implement a Repository and Manager layers with an appropriate conditions:
@Entity
@Table(name="order")
public class Order {
...
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = { ... })
private List<Part> parts;
}
@Entity
@Table(name="part")
public class Part {
...
@JoinColumn(name = "r_order_id", referencedColumnName = "id")
@ManyToOne(...)
private Order order;
@Column(...)
private PartType partType;
@Column(...)
private String code;
@Column(...)
private String description;
}
public interface PartInterface implements CrudRepository<Part, Long> {
List<Part> findByOrderIdAndPartType(Long orderId, PartType partType);
}
@Component
public class PartManager {
@Autowired
private PartInterface partInterface;
public List<Part> getGlassPartsByOrderId(Long orderId) {
return List<Part> partInterface.findByOrderIdAndPartType(orderId, PartType.GLASS);
}
public List<Part> getNonGlassPartsByOrderId(Long orderId) {
return List<Part> partInterface.findByOrderIdAndPartType(orderId, PartType.NON_GLASS);
}
}
The second one is to filter all the parts of the order by the type:
public interface OrderInterface implements CrudRepository<Order, Long> {
@Override
Order findOne(Long orderId);
}
@Component
public class OrderManager {
@Autowired
private OrderInterface orderInterface;
public List<Part> getGlassPartsByOrderId(Long orderId) {
return getOrderParts(orderId).stream().filter(part -> Objects.equals(PartType.GLASS, part.getPartType())).collect(Collectors.toList());
}
public List<Part> getNonGlassPartsByOrderId(Long orderId) {
return getOrderParts(orderId).stream().filter(part -> Objects.equals(PartType.NON_GLASS, part.getPartType())).collect(Collectors.toList());
}
private List<Part> getOrderParts(Long orderId) {
Order order = orderInterface.findOne(Long orderId);
if (Objects.isNull(order) || Objects.isNull(order.getParts())) {
return Collections.emptyList();
} else {
return order.getParts();
}
}
}
Actually there is another one option - to filter parts inside the entity on the fly:
@Entity
@Table(name="order")
public class Order {
@OneToMany(...)
private List<Part> parts;
public List<Part> getGlassParts{
if (Objects.nonNull(parts)) {
return parts.stream().filter(part -> Objects.equals(PartType.GLASS, part.getPartType())).collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
public List<Part> getNonGlassParts{
if (Objects.nonNull(parts)) {
return parts.stream().filter(part -> Objects.equals(PartType.NON_GLASS, part.getPartType())).collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
}
UPDATE Since you're using Hibernate
there is an ORM-dependent option to get the desired result it's a @JoinColumnOrFormula
annotation that is available for Hibernate
only:
@Entity
@Table(name="order")
public class Order {
@OneToMany(...)
@JoinColumnOrFormula(
column = @JoinColumn(name = "id", referencedColumnName = "r_order_id", insertable = false, updatable = false)
,formula = @JoinFormula(value = PartType.GLASS_STR_VALUE, referencedColumnName = "partType"))
private List<Part> glassParts;
@OneToMany(...)
@JoinColumnOrFormula(
column = @JoinColumn(name = "id", referencedColumnName = "r_order_id", insertable = false, updatable = false)
,formula = @JoinFormula(value = PartType.NON_GLASS_STR_VALUE, referencedColumnName = "partType"))
private List<Part> nonGlassParts;
}
Please pay your attention that the value parameter inside the @JoinFormula
clause must be a String
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.