Guten Tag liebe Forumsteilnehmer.
Kurz zu meiner Project Idee :
Ich möchte gerne eine Bilderverwaltung programmieren. Dazu möchte ich Meta-Daten aus Fotos auslesen und in Property Objekten speichern. Später möchte ich nach diesen Properties filter über eine Webanwendung.
Für die Bilder habe ich folgende Entity Klasse :
DIe Properties is eine abstracte Klasse :
Als Beispiel zeige ich hier mal das Album Property
Was ist nun das Problem. Bisher wurden die Bilder aus einem Verzeichnis ausgelesen und in einem Image Service gebaut und gespeichert. Allerdings wurden die Properties immer neu angelegt. Also so gab es das Album Property (für das Test Album) in jedem Image. Ich möchte aber, dass Properties unique sind. Also es soll nur einmal das Album Property für "Test Album1" und 1x für "Test Album2" geben.
Dazu habe ich in dem Image Repository folgende Funktion hinzugefügt :
Das Speichern und Bauen des ersten Bildes funktioniert super.
Allerdings bekomme ich die Exception :
Wenn ich das Bild (Image) an dieser Stelle baue:
Ich bin mir bewusst, dass es ziemlich viel Code ist, hoffe aber, dass ich das Problem einigermaßen erklärt hat und mir jemand einen Tipp geben kann.
Vielen Dank für euere Zeit und die Hilfe !
Kurz zu meiner Project Idee :
Ich möchte gerne eine Bilderverwaltung programmieren. Dazu möchte ich Meta-Daten aus Fotos auslesen und in Property Objekten speichern. Später möchte ich nach diesen Properties filter über eine Webanwendung.
Für die Bilder habe ich folgende Entity Klasse :
Java:
@Builder(setterPrefix = "with", toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@Table(name = "IMAGE")
@ToString
public class Image {
@Id
@GeneratedValue
@Column(updatable = false, unique = true)
private long ID;
@NonNull
@Column(updatable = false, unique = true)
private String hashValue;
@NonNull
private String filePath;
@Singular
@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private Collection<Property> properties;
}
DIe Properties is eine abstracte Klasse :
Code:
@SuperBuilder(setterPrefix = "with")
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@ToString
public abstract class Property {
@Id
@GeneratedValue
@Column(updatable = false, unique = true)
@Getter
private long ID;
public abstract PropertyCategory getCategory();
}
Als Beispiel zeige ich hier mal das Album Property
Java:
@SuperBuilder(setterPrefix = "with")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@DiscriminatorValue("ALBUM_PROPERTY")
@ToString(callSuper = true)
@EqualsAndHashCode
public class AlbumProperty extends Property {
private final PropertyCategory category = PropertyCategory.ALBUM;
@NonNull
private String albumName;
}
Was ist nun das Problem. Bisher wurden die Bilder aus einem Verzeichnis ausgelesen und in einem Image Service gebaut und gespeichert. Allerdings wurden die Properties immer neu angelegt. Also so gab es das Album Property (für das Test Album) in jedem Image. Ich möchte aber, dass Properties unique sind. Also es soll nur einmal das Album Property für "Test Album1" und 1x für "Test Album2" geben.
Dazu habe ich in dem Image Repository folgende Funktion hinzugefügt :
Code:
default Optional<Property> findAlbumProperty(String albumName) {
return findAll().stream()
.map(Image::getProperties)
.flatMap(Collection::stream)
.filter(property -> property.getCategory().equals(PropertyCategory.ALBUM))
.filter(property -> ((AlbumProperty) property).getAlbumName().equals(albumName))
.findFirst();
}
Das Speichern und Bauen des ersten Bildes funktioniert super.
Allerdings bekomme ich die Exception :
Code:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: my.mediaservice.image.property.Property
Wenn ich das Bild (Image) an dieser Stelle baue:
Code:
protected Image buildImageObject(@Nonnull File imageFile, @Nonnull String albumName, @Nonnull ImageStatus
imageStatus, @Nonnull String hashValue) {
if (!FilenameUtils.getExtension(imageFile.getAbsolutePath()).equalsIgnoreCase("jpg"))
throw new IllegalArgumentException(imageFile.getAbsolutePath() + " is not an image");
HashSet<Property> properties = Sets.newHashSet();
val albumProperty = repository.findAlbumProperty(albumName).orElseGet(() -> propertyService.buildAlbumProperty(albumName));
/*if (albumProperty != null) properties.add(albumProperty);
val statusProperty = (StatusProperty) repository.findStatusProperty(imageStatus)
.orElseGet(() -> propertyService.buildStatusProperty(imageStatus));
if (statusProperty != null) properties.add(statusProperty);
val dimensionProperty = propertyService.buildDimensionProperty(imageFile);
if (dimensionProperty != null) properties.add(dimensionProperty);
try {
val locationProperty = propertyService.buildLocationProperty(imageFile);
if (locationProperty != null) properties.add(locationProperty);
} catch (PropertyException e) {
log.debug("ignore location property of {} because of {}", kv("image file", imageFile.getAbsolutePath()), kv("error", e.getMessage()));
}
try {
val timeStampProperty = propertyService.buildTimeStampProperty(imageFile);
if (timeStampProperty != null) properties.add(timeStampProperty);
} catch (PropertyException e) {
log.debug("ignore timestamp property of {} because of {}", kv("image file", imageFile.getAbsolutePath()), kv("error", e.getMessage()));
}
*/
return Image.builder()
.withHashValue(hashValue)
.withFilePath(imageFile.getAbsolutePath())
.withProperties(properties)
.build();
}
Ich bin mir bewusst, dass es ziemlich viel Code ist, hoffe aber, dass ich das Problem einigermaßen erklärt hat und mir jemand einen Tipp geben kann.
Vielen Dank für euere Zeit und die Hilfe !