ayylmao123xdd
ayylmao123xdd
JCHJava Community | Help. Code. Learn.
Created by ayylmao123xdd on 1/15/2025 in #java-help
fetch subclasses and their associations with one query
demo for simplicity and to avoid being sued :GnuTrolling: so the question is whether its possible to fetch all the associations to their respective classes when calling the find all method without eager fetching and avoiding n+1 and without extra queries for getting the associations
public interface ShapeRepository extends JpaRepository<Shape, Long> {
Page<Shape> findAll();
}
public interface ShapeRepository extends JpaRepository<Shape, Long> {
Page<Shape> findAll();
}
@DiscriminatorValue("SQUARE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Square extends Shape {
@OneToMany(mappedBy = "square", fetch = FetchType.LAZY)
private Set<Vertices>;
}
@DiscriminatorValue("SQUARE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Square extends Shape {
@OneToMany(mappedBy = "square", fetch = FetchType.LAZY)
private Set<Vertices>;
}
@DiscriminatorValue("TRIANGLE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Triangle extends Shape {
@OneToMany(mappedBy = "triangle", fetch = FetchType.LAZY)
private Set<Angles>;
}
@DiscriminatorValue("TRIANGLE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Triangle extends Shape {
@OneToMany(mappedBy = "triangle", fetch = FetchType.LAZY)
private Set<Angles>;
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public abstract class Shape {
@Id
private long id;

private String name;
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public abstract class Shape {
@Id
private long id;

private String name;
}
@DiscriminatorValue("RECTANGLE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Rectangle extends Shape {
@OneToMany(mappedBy = "rectangle", fetch = FetchType.LAZY)
private Set<Sides>;
}
@DiscriminatorValue("RECTANGLE")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Rectangle extends Shape {
@OneToMany(mappedBy = "rectangle", fetch = FetchType.LAZY)
private Set<Sides>;
}
33 replies
JCHJava Community | Help. Code. Learn.
Created by ayylmao123xdd on 1/13/2025 in #java-help
left fetch join creates race condition with optimistic locking
if i use query to left join authors books the test suddenly doesnt pass made a demo for simplicity
@Service
@RequiredArgsConstructor
public class BookService {
private final BookRepository repository;
private final AuthorRepository authorRepository;
private final BookMapper mapper;

@Transactional
public void addBook(long id, CreateBookCommand command) {
Author author = authorRepository.findWithLockingById(id)
.orElseThrow(() -> new EntityNotFoundException(MessageFormat
.format("Author with id={0} not found", id)));
if (author.getBooks().isEmpty()) {
Book book = mapper.mapFromCommand(command);
book.setAuthor(author);
repository.save(book);
} else {
throw new RuntimeException("Author cannot have more than 1 book");
}
}
}
@Service
@RequiredArgsConstructor
public class BookService {
private final BookRepository repository;
private final AuthorRepository authorRepository;
private final BookMapper mapper;

@Transactional
public void addBook(long id, CreateBookCommand command) {
Author author = authorRepository.findWithLockingById(id)
.orElseThrow(() -> new EntityNotFoundException(MessageFormat
.format("Author with id={0} not found", id)));
if (author.getBooks().isEmpty()) {
Book book = mapper.mapFromCommand(command);
book.setAuthor(author);
repository.save(book);
} else {
throw new RuntimeException("Author cannot have more than 1 book");
}
}
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String firstName;

private String lastName;

@OneToMany(mappedBy = "author", fetch = FetchType.EAGER)
private Set<Book> books;
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String firstName;

private String lastName;

@OneToMany(mappedBy = "author", fetch = FetchType.EAGER)
private Set<Book> books;
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String title;

private String description;

private long price;

@ManyToOne
private Author author;
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String title;

private String description;

private long price;

@ManyToOne
private Author author;
}
163 replies
JCHJava Community | Help. Code. Learn.
Created by ayylmao123xdd on 10/24/2024 in #java-help
handling lost update problem happening with one thread updating a resource at a time
so i got this quite an interesting problem where i got a piece of code that edits a entity there is one class and a bunch of other classes that inherit it the superclass has a version field for optimistic locking all subclasses are stored in the same jpa repository the lost update/stale data problem comes when sending an update command example scenario employee gets updated salary to 3000 but the request will sent later employee gets updated salary to 5000 but the request is sent immediately so the employee gets 3000 salary even though he was supposed to have 5000 i was thinking of comparing the version of the entity and the version thats sent in the command but that generates race condition example code
@Transactional
public Dto edit(long id, EditCommand command) {
try {
Subclass subclass = repository.findWithLockingById(id)
.orElseThrow();
// if (command.getVersion() != subclass.getVersion()) {
// } generates race condition
service.update(command, subclass);
return mapper.mapToDto(subclass);
}
@Transactional
public Dto edit(long id, EditCommand command) {
try {
Subclass subclass = repository.findWithLockingById(id)
.orElseThrow();
// if (command.getVersion() != subclass.getVersion()) {
// } generates race condition
service.update(command, subclass);
return mapper.mapToDto(subclass);
}
349 replies