Embeddable is null so auditing does not work - java

I have the following embeddable
#Data
#Embeddable
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class BaseEntity {
#CreatedDate
#Column(name = "created_date")
private LocalDateTime createdDate;
}
Which I embedded into another entity like this
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "room")
#Builder
public class room {
#Id
#GeneratedValue
private UUID id;
#JsonUnwrapped
#Embedded
private BaseEntity baseEntity;
#Column(length = 80, nullable = false)
private String name;
}
Now when I save a room entity the embedded BaseEntity is null and that is why nothing is audited. According to https://docs.spring.io/spring-data/commons/docs/2.4.4/reference/html/#auditing.annotations it should just work like this. How can I fix this behaviour ?

#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "room")
#Builder
public class room {
...
#JsonUnwrapped
#Embedded
private BaseEntity baseEntity = new BaseEntity();
...
}

Related

JPA/Hibernate OneToMany relationship from Embedded entity by non-PK columns

JPA Model:
#Getter
#Setter
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "BASE_RECORD")
public class BaseRecord {
#Id
#Column(name = "DB_ID")
public Long id;
#Embedded
public DeclarantRecord declarant;
}
#Getter
#Setter
#Embeddable
#AllArgsConstructor
#NoArgsConstructor
public class DeclarantRecord {
#Column(name = "DECLARANT_ID")
public String declarantId;
#Column(name = "DECLARANT_IDE")
public String identificationNumber;
#Column(name = "DECLARANT_NAME")
public String name;
#OneToMany(mappedBy = "baseRecord", fetch = FetchType.EAGER)
public List<DeclarantAddress> addresses;
}
#Getter
#Setter
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "ADDRESS_RECORD")
public class DeclarantAddress {
#Id
#Column(name = "DB_ID")
public Long id;
#ManyToOne
#JoinColumn(name = "PERS_ID", referencedColumnName = "DECLARANT_ID")
public BaseRecord baseRecord;
}
When fetching a BaseRecord from DB by using a Spring Boot JPARepository, I receive the following exception:
Caused by: org.hibernate.AnnotationException: referencedColumnNames(DECLARANT_ID) of DeclarantAddress.baseRecord referencing BaseRecord not mapped to a single property
I cannot understand what's wrong and moreover, if I inline the DeclarantRecord in the BaseRecord entity by declaring all the properties in there and moving the exact same relationship declaration in the BaseRecord class, everything works perfectly.
The answer that worked for me:
Move
#Column(name = "DECLARANT_ID") public String declarantId; to BaseRecord class.
The rest can stay the same.

CascadeType for updating entity in relation #ManyToOne

I have two Entities in relation #ManyToOne:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "TRIPS")
public class Trip {
#Id
#GeneratedValue
#NotNull
#Column(name = "ID", unique = true)
int tripId;
#OneToMany(
targetEntity = Audit.class,
mappedBy = "tripId",
fetch = FetchType.LAZY
)
private List<Audit> audits = new ArrayList<>();
}
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table
public class Audit {
#Id
#GeneratedValue
#NotNull
#Column(unique = true)
public int auditId;
#ManyToOne
#JoinColumn(name = "TRIP_ID")
public Trip tripId;
}
When I'm trying to:
Audit audit = new Audit();
auditDao.save(audit);
List<Audit> audits = new ArrayList<>();
audits.add(audit);
Trip trip = new Trip(audits);
I get exception: detached entity passed to persist.
I tried to change CascadeType to MERGE, but it didn't help.
Where's the problem. Is there maybe other way?

Spring Boot auto generate association table with attibute

I'm auto generating entities within the database which works great using:
spring.jpa.hibernate.ddl-auto=update
Now I need an additional attribute within the association table and I can't figure it out without creating an association entity by hand. The current classes listed below generate an association table without the additional attribute.
The tables I need:
persons:
id
search_requests:
id
search_requests_persons:
person_id
search_request_id
study_id
The classes I currently have (simplified):
#NoArgsConstructor
#RequiredArgsConstructor(staticName = "of")
#Getter
#Setter
#Entity
#EqualsAndHashCode
#Table(name = "persons")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
// The following line is what I would need
// private List<Integer> studyIds;
}
#NoArgsConstructor
#RequiredArgsConstructor(staticName = "of")
#Getter
#Setter
#Entity
#EqualsAndHashCode
#Table(name = "search_requests")
public class SearchRequest {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
#NonNull
#ManyToMany
private List<Person> persons;
}
I'm using Lombok and Javax Persistence for the annotations.
In order to add additional attributes in your JoinTable, you could manually create your JoinTable entity. e.g:
PersonSearchRequest.java
#Entity
#Table(name = "person_search_request)
#Getter
#Setter
#NoArgsConstructor
public class PersonSearchRequest {
#EmbeddedId
private PersonSearchRequestPK id;
// put your additional attribute here, e.g:
private String attribute1;
private Long attribute2;
#ElementCollection
private List<String> attribute3s;
#Embeddable
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public static class PersonSearchRequestPK implements Serializable {
#ManyToOne(fetch = FetchType.LAZY)
private Person person;
#ManyToOne(fetch = FetchType.LAZY)
private SearchRequest searchRequest;
}
}
Person.java
#NoArgsConstructor
#RequiredArgsConstructor(staticName = "of")
#Getter
#Setter
#Entity
#EqualsAndHashCode
#Table(name = "persons")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
#OneToMany(mappedBy = "id.person")
private List<PersonSearchRequest> personSearchRequests;
}
SearchRequest.java
#NoArgsConstructor
#RequiredArgsConstructor(staticName = "of")
#Getter
#Setter
#Entity
#EqualsAndHashCode
#Table(name = "search_requests")
public class SearchRequest {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
#OneToMany(mappedBy = "id.searchRequest")
private List<PersonSearchRequest> personSearchRequests;
}

Spring, Hibernate: "collection owner not associated with session" when trying to delete

I have this problem where trying to delete a parent object via crud repository, I'm getting this error message:
"collection owner not associated with session: ClassA.things"
This error appeared after splitting one class into three (two classes extend the main classA), but I haven't done any other changes, I haven't touched this OneToMany relationship. So right now it looks approximately like this:
Class A:
#Table
#Entity(name = "ClassA")
#Inheritance(strategy = InheritanceType.JOINED)
#Getter #Setter #NoArgsConstructor #ToString
public class ClassA {
#Column(name = "ClassA_id")
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToMany(mappedBy = "classA", orphanRemoval = true)
private Collection<Thing> things;
...etc, other fields
}
Class B and C (both extend class A):
#Table
#Entity(name = "ClassB")
#Getter #Setter #NoArgsConstructor
public class ClassB extends ClassA {
#Column(name = "ClassB_id")
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
...etc, other fields
}
#Table
#Entity(name = "ClassC")
#Getter #Setter #NoArgsConstructor
public class ClassC extends ClassA {
#Column(name = "ClassC_id")
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
...etc, other fields
}
And here's the Thing class, which the ClassA has a collection of with #OneToMany relationship:
#Table
#Entity(name = "Ratings")
#Getter #Setter #NoArgsConstructor
public class Thing {
#Column(name = "Thing_id")
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Setter(value = AccessLevel.PRIVATE)
private int id;
#ManyToOne
#JoinColumn(name = "ClassA_id")
private ClassA classA;
...etc, other fields
}
Finally, here's the controller method where DELETE is being called to delete ClassB, for example:
#Transactional
#DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteClassB(#PathVariable(name = "id") int id) {
if (classBservice.delete(id)) {
return ResponseEntity.ok().build();
} else {
return ResponseEntity.badRequest().build();
}
}
try to remove the id members from ClassB and ClassC since they are inherited from ClassA.

How do I use the jpa/hibernate annotation mapping to Set<Entity> and the Entity is composite primary key

#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity(name = "users")
#ToString
#Table(name = "users")
#Embeddable
public class User implements UserDetails{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id",unique=true)
private Long id;
#OneToMany
#Cascade({CascadeType.ALL })
#JoinTable(name = "users_authorities")
private Set<SimpleGrantedAuthority> authorities;
}
This is my User.java,and have a porperty private Set<SimpleGrantedAuthority> authorities. I want use jpa/hibernate mapping to another Entity SimpleGrantedAuthority.
#Data
#Entity(name = "authorities")
#Embeddable
#Table(name = "authorities", uniqueConstraints={#UniqueConstraint(columnNames={"authority","username"})})
class SimpleGrantedAuthority implements GrantedAuthority {
private Long id;
#Column(name = "authority")
private String authority;
#Column(name = "username")
private String username;
}
This is SimpleGrantedAuthority .java,How do I write the correct annotation to map Set<SimpleGrantedAuthority> authorities; to SimpleGrantedAuthority.javaabove private Set<SimpleGrantedAuthority> authorities;
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity: com.as.backend.antscience.entity.SimpleGrantedAuthority
if you need an express composite key in JPA , you have to write as below.
first , define composite key as class and put a #Embeddable annotation.
and define that Id class as member of entitiy class and put #EmbeddedId
#Data
#Entity(name = "authorities")
#Embeddable
#Table(name = "authorities", uniqueConstraints={#UniqueConstraint(columnNames={"authority","username"})})
class SimpleGrantedAuthority implements GrantedAuthority {
#EmbeddedId
private Id id;
#Embeddable
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Data
public static class Id implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "authority")
private String authority;
#Column(name = "username")
private String username;
}
}
#JoinColumns annotation is probably what you are looking for.
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumns.html

Categories

Resources