What you can do is to use javax.persistence.AttributeConverter and create curve converter like this:
public class CurveConverter implements AttributeConverter<Curve, String> {
private static final String SEPARATOR1 = ",";
private static final String SEPARATOR2 = ";";
@Override
public String convertToDatabaseColumn(Curve curve) {
if (curve == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for(CurvePoint curvePoint:curve.getPoints()){
sb.append(curvePoint.getTorque());
sb.append(SEPARATOR1);
sb.append(curvePoint.getSpeed());
sb.append(SEPARATOR2);
}
sb.setLength(sb.length() - SEPARATOR2.length());
return sb.toString();
}
@Override
public Curve convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isEmpty()) {
return null;
}
String[] pieces = dbData.split(SEPARATOR2);
if (pieces == null || pieces.length == 0) {
return null;
}
List<CurvePoint> curvePoints = new ArrayList<>();
for(String piece:pieces){
String[] numbers = piece.split(SEPARATOR1);
curvePoints.add(new CurvePoint(Float.parseFloat(numbers[0]), Float.parseFloat(numbers[1])));
}
return Curve.builder().points(curvePoints).build();
}
}
which will store your curve as string (CSV – “1.1,2.2;3.3,4.4 …”) to table as one attribute. You will get rid of joints and it will be faster. This is only good when the curve is immutable (all points are changing at once)
Then you just add annotation on field in entity where the curve is used like this:
@Column(name = "curve", length = 10000)
@Basic(fetch = FetchType.LAZY)
@Convert(converter = CurveConverter.class)
Curve curve;
Important here is to set correct length of the string. Also check that @Basic(fetch = FetchType.LAZY)
is used to load the curve data lazy (only when we need them). The annotation @Convert(converter = CurveConverter.class)
then says to hibernate that before saving this field to database it will be converted using our newly created curve CurveConvertor (same when we will get the data from DB).
CLICK HERE to find out more related problems solutions.