Add a reproducer for spring-projects/spring-framework#31534
This commit is contained in:
@@ -7,6 +7,9 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||
constraints {
|
||||
implementation("org.springframework:spring-orm:6.1.0-SNAPSHOT")
|
||||
}
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
|
||||
runtimeOnly("com.h2database:h2")
|
||||
|
||||
@@ -108,4 +108,14 @@ class DataJpaApplicationAotTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void listRecipients(AssertableOutput output) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
|
||||
assertThat(output)
|
||||
.hasSingleLineContaining(
|
||||
"listRecipients(): recipient = Recipient{id=1, address=Address[street=Paul Bert, city=Lyon, postalCode=69003]}");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.example.data.jpa;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.example.data.jpa.model.Address;
|
||||
import com.example.data.jpa.model.Recipient;
|
||||
import com.example.data.jpa.model.Voucher;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
@@ -12,14 +14,19 @@ public class NonTransactionalRunner implements CommandLineRunner {
|
||||
|
||||
private final VoucherRepository voucherRepository;
|
||||
|
||||
public NonTransactionalRunner(VoucherRepository voucherRepository) {
|
||||
private final RecipientRepository recipientRepository;
|
||||
|
||||
public NonTransactionalRunner(VoucherRepository voucherRepository, RecipientRepository recipientRepository) {
|
||||
this.voucherRepository = voucherRepository;
|
||||
this.recipientRepository = recipientRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
insertVouchers();
|
||||
insertRecipients();
|
||||
listVouchers();
|
||||
listRecipients();
|
||||
}
|
||||
|
||||
private void insertVouchers() {
|
||||
@@ -32,4 +39,13 @@ public class NonTransactionalRunner implements CommandLineRunner {
|
||||
vouchers.forEach(voucher -> System.out.printf("listVouchers(): voucher = %s%n", voucher));
|
||||
}
|
||||
|
||||
private void insertRecipients() {
|
||||
this.recipientRepository.save(new Recipient(1L, new Address("Paul Bert", "Lyon", "69003")));
|
||||
}
|
||||
|
||||
private void listRecipients() {
|
||||
List<Recipient> recipients = this.recipientRepository.findAll();
|
||||
recipients.forEach(recipient -> System.out.printf("listRecipients(): recipient = %s%n", recipient));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.example.data.jpa;
|
||||
|
||||
import com.example.data.jpa.model.Recipient;
|
||||
|
||||
import org.springframework.data.repository.ListCrudRepository;
|
||||
|
||||
interface RecipientRepository extends ListCrudRepository<Recipient, Long> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.data.jpa.model;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
import org.hibernate.annotations.EmbeddableInstantiator;
|
||||
|
||||
@Embeddable
|
||||
@EmbeddableInstantiator(AddressInstantiator.class)
|
||||
public record Address(String street, String city, String postalCode) {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.data.jpa.model;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.ValueAccess;
|
||||
|
||||
public class AddressInstantiator implements EmbeddableInstantiator {
|
||||
|
||||
@Override
|
||||
public Object instantiate(ValueAccess valueAccess, SessionFactoryImplementor sessionFactory) {
|
||||
final Object[] values = valueAccess.getValues();
|
||||
final String city = (String) values[0];
|
||||
final String postalCode = (String) values[1];
|
||||
final String street = (String) values[2];
|
||||
return new Address( street, city, postalCode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) {
|
||||
return object instanceof Address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) {
|
||||
return object.getClass().equals(Address.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.example.data.jpa.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Recipient {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@Embedded
|
||||
private Address address;
|
||||
|
||||
public Recipient() {
|
||||
}
|
||||
|
||||
public Recipient(Long id, Address address) {
|
||||
this.id = id;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Recipient recipient = (Recipient) o;
|
||||
return Objects.equals(id, recipient.id) && Objects.equals(address, recipient.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Recipient{" +
|
||||
"id=" + id +
|
||||
", address=" + address +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user