'Call for understanding how the subclass entity is automatically mapped and saved
I have 2 entities for now namely L100 and L218 as follows and both of them contains a Discriminator Value and extends a Super Class entity ATUPosition which consists of the main @Table annotation as follows:
L100
@Setter
@Getter
@Entity
@EqualsAndHashCode(callSuper = true)
@DiscriminatorValue("L100")
public class L100 extends ATUPosition {
@Column(name = "pos_s_nocli_dos", length = 6)
@CsvBindByPosition(position = 0)
@Size(message = "nocliDos cannot be greater than 6 characters", max = 6)
private String nocliDos;
@Column(name = "pos_s_cocons", length = 1)
@CsvBindByPosition(position = 1)
@Size(message = "cocons cannot be greater than 1 character", max = 1)
private String cocons;
// remaining columns below
L218
@Setter
@Getter
@Entity
@EqualsAndHashCode(callSuper = true)
@DiscriminatorValue("L218")
public class L218 extends ATUPosition {
@Column(name = "pos_s_coste_nouv", length = 4)
@CsvBindByPosition(position = 0)
@Size(message = "costeNouv cannot be greater than 4 characters", max = 4)
private String costeNouv;
@Column(name = "pos_s_comonl_iso_rs", length = 3)
@CsvBindByPosition(position = 1)
@Size(message = "comonlIsoRs cannot be greater than 3 characters", max = 3)
private String comonlIsoRs;
//remaining columns below
ATUPosition
@Entity
@Table(name = "Positions")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
discriminatorType = DiscriminatorType.STRING,
name = "pos_s_type",
length = 10
)
@AttributeOverride(name = "uid", column = @Column(name = "pos_n_id"))
@AttributeOverride(name = "filename", column = @Column(name = "pos_s_filename"))
@AttributeOverride(name = "internalFilename", column = @Column(name = "pos_s_int_filename"))
@AttributeOverride(name = "fileDate", column = @Column(name = "pos_d_filedate"))
@AttributeOverride(name = "createdDate", column = @Column(name = "pos_d_creation", nullable = false, updatable = false))
@AttributeOverride(name = "createdVisa", column = @Column(name = "pos_s_created_visa", nullable = false))
@AttributeOverride(name = "lastModificationDate", column = @Column(name = "pos_d_lastupdate", nullable = false))
@AttributeOverride(name = "lastModificationVisa", column = @Column(name = "pos_s_lastupdate_visa", nullable = false))
@Getter
@Setter
public abstract class ATUPosition extends AEntity {
@Enumerated(EnumType.STRING)
@Column(name = "pos_s_position_state")
protected PositionState positionState;
@Enumerated(EnumType.STRING)
@Column(name = "pos_s_forex_extracted",length = 5)
protected ExtractionState exchangeRateExtracted;
Now I have a method am calling to convert a CSV to these column values and the list returned is a list of ATUPosition. Below is the method:
public List<ATUPosition> createCsvToBeanBuilderPositionDTO(@Nonnull File file,Class<? extends ATUPosition> clazz, String dto) throws IOException {
log.info("Creating CSV for bean: {}", dto);
return new CsvToBeanBuilder<ATUPosition>(new InputStreamReader(new FileInputStream(file)))
.withType(clazz)
.withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_QUOTES)
.withSeparator(Constants.DELIMITER[0])
.withIgnoreLeadingWhiteSpace(false)
.build()
.parse();
}
After calling the method, I am able to save the entity as follows:
private long saveEntity(File file, Class<? extends ATUPosition> clazz, String csvFileName, String multiPartFileName) throws IOException {
PositionConverter positionConverter = new PositionConverter();
List<ATUPosition> listOfEntities = positionConverter.createCsvToBeanBuilderPositionDTO(file, clazz, csvFileName);
long size = listOfEntities.stream()
.map(entity -> {
entity.setFilename(FilenameUtils.getName(multiPartFileName));
entity.setInternalFilename(entity.getFilename());
entity.setCreatedVisa("AUTO");
entity.setLastModificationVisa("AUTO");
entity.setFileDate(FileUtils.extractLocalDateFromFilename(FilenameUtils.getBaseName(multiPartFileName)));
return entity;
})
.map(positionRepository::save)
.count();
Files.deleteIfExists(file.toPath());
return (int) size;
}
What I wish to understand is how is the CsvToBeanBuilder is able to return the specific entity am parsing depending on the Class attribute and how my PositionRepository below is able to save all the values such that my entity is a subclass of ATUPosition. My repo is as below:
public interface PositionRepository<T extends ATUPosition> extends ATUPositionRepository<T> {
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
