mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-21 20:06:00 +00:00
Merge pull request #2380 from cit-consulting/isToManyDirty_cce
WIP: Try to fix ClassCastException in isToManyDirty() check
This commit is contained in:
@@ -2875,8 +2875,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
final EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
for (BeanPropertyAssocMany<?> many : propertiesManySave) {
|
||||
if (ebi.isLoadedProperty(many.propertyIndex())) {
|
||||
final BeanCollection<?> value = (BeanCollection<?>) many.getValue(bean);
|
||||
if (value != null && value.hasModifications()) {
|
||||
final Object value = many.getValue(bean);
|
||||
if (value instanceof BeanCollection && ((BeanCollection<?>)value).hasModifications() || value != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.tests.model.basic.EBasicVer;
|
||||
import org.tests.model.basic.Order;
|
||||
import org.tests.model.basic.OrderShipment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -176,6 +177,38 @@ public class TestTransparentPersist extends BaseTestCase {
|
||||
DB.delete(Customer.class, c0.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertWithPersistCascadeInsert() {
|
||||
|
||||
// setup data
|
||||
Customer c0 = new Customer();
|
||||
c0.setName("firstCust");
|
||||
DB.save(c0);
|
||||
|
||||
Integer orderId;
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
transaction.setAutoPersistUpdates(true); // EXPERIMENTAL feature
|
||||
Order order = new Order();
|
||||
order.setStatus(Order.Status.NEW);
|
||||
order.setCustomer(c0);
|
||||
order.setShipments(new ArrayList<>());
|
||||
DB.insert(order);
|
||||
orderId = order.getId();
|
||||
// cascade persist will insert this Shipment (even though it isn't in the persistence context)
|
||||
OrderShipment osh0 = new OrderShipment();
|
||||
order.addShipment(osh0);
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
Order checkOrder = DB.find(Order.class, orderId);
|
||||
|
||||
assertThat(checkOrder.getStatus()).isEqualTo(Order.Status.NEW);
|
||||
assertThat(checkOrder.getShipments().size()).isEqualTo(1);
|
||||
|
||||
DB.delete(checkOrder);
|
||||
DB.delete(Customer.class, c0.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateReferenceOnlyWithPersistCascade_Insert_andUpdateForeignKey() {
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
<modules>
|
||||
<module>test-java16</module>
|
||||
<module>test-kotlin</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>java11-oss</artifactId>
|
||||
<version>2.3</version>
|
||||
</parent>
|
||||
|
||||
<name>kotlin test</name>
|
||||
<description>Kotlin specific tests</description>
|
||||
<artifactId>test-kotlin</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
|
||||
<ebean-maven-plugin.version>12.11.5</ebean-maven-plugin.version>
|
||||
<kotlin.version>1.5.31</kotlin.version>
|
||||
<jackson.version>2.12.1</jackson.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>12.11.6-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>12.11.6-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<configuration>
|
||||
<jvmTarget>11</jvmTarget>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-maven-plugin</artifactId>
|
||||
<version>${ebean-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
<phase>process-test-classes</phase>
|
||||
<configuration>
|
||||
<transformArgs>debug=1</transformArgs>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>testEnhance</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- TODO remove. May be enable signing in release profile? -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebean.test.kotlin
|
||||
|
||||
import io.ebean.DB
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.example.order.Customer
|
||||
import org.example.order.Order
|
||||
import org.example.order.OrderItem
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class TransparentPersistenceTest {
|
||||
|
||||
@Test
|
||||
fun `insert with cascade insert`() {
|
||||
// setup data
|
||||
|
||||
// setup data
|
||||
val c0 = Customer("Customer 0")
|
||||
DB.save(c0)
|
||||
|
||||
var orderId: Long
|
||||
DB.beginTransaction().use { transaction ->
|
||||
transaction.setAutoPersistUpdates(true) // EXPERIMENTAL feature
|
||||
val order = Order(c0)
|
||||
DB.insert(order)
|
||||
orderId = order.id
|
||||
// cascade persist will insert this OrderItem (even though it isn't in the persistence context)
|
||||
order.items.add(OrderItem(order, "item 0", BigDecimal.TEN))
|
||||
transaction.commit()
|
||||
}
|
||||
|
||||
val checkOrder = DB.find(Order::class.java, orderId)
|
||||
|
||||
assertNotNull(checkOrder)
|
||||
assertThat(checkOrder.items.size).isEqualTo(1)
|
||||
|
||||
DB.delete(checkOrder)
|
||||
DB.delete(c0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.example.order
|
||||
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.Version
|
||||
|
||||
@Entity
|
||||
class Customer(
|
||||
name: String,
|
||||
) {
|
||||
@Id
|
||||
var id: Int = 0
|
||||
val name: String = name
|
||||
|
||||
@Version
|
||||
var version: Long = 0
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.example.order
|
||||
|
||||
import javax.persistence.CascadeType
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.ManyToOne
|
||||
import javax.persistence.OneToMany
|
||||
import javax.persistence.Table
|
||||
import javax.persistence.Version
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_order")
|
||||
class Order(
|
||||
customer: Customer,
|
||||
) {
|
||||
@Id
|
||||
val id: Long = 0
|
||||
|
||||
@ManyToOne
|
||||
val customer: Customer = customer
|
||||
|
||||
@OneToMany(mappedBy = "order", cascade = [CascadeType.ALL], orphanRemoval = true)
|
||||
val items: MutableList<OrderItem> = mutableListOf()
|
||||
|
||||
@Version
|
||||
val version: Long = 0
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.example.order
|
||||
|
||||
import java.math.BigDecimal
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.ManyToOne
|
||||
|
||||
@Entity
|
||||
class OrderItem(
|
||||
order: Order,
|
||||
name: String,
|
||||
price: BigDecimal,
|
||||
amount: Int = 1,
|
||||
description: String? = null,
|
||||
) {
|
||||
@Id
|
||||
val id: Long = 0
|
||||
|
||||
@ManyToOne
|
||||
val order: Order = order
|
||||
|
||||
val name: String = name
|
||||
|
||||
val description: String? = description
|
||||
|
||||
val amount: Int = amount
|
||||
|
||||
val price: BigDecimal = price
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
ebean:
|
||||
test:
|
||||
platform: h2
|
||||
ddlMode: dropCreate
|
||||
dbName: foo
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
<logger name="org.avaje" level="TRACE"/>
|
||||
<logger name="io.ebean" level="INFO"/>
|
||||
|
||||
<logger name="io.ebean.docker" level="TRACE"/>
|
||||
<logger name="io.ebean.DDL" level="DEBUG"/>
|
||||
|
||||
<logger name="io.ebean.SQL" level="TRACE"/>
|
||||
<logger name="io.ebean.TXN" level="TRACE"/>
|
||||
<logger name="io.ebean.SUM" level="TRACE"/>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user