jmix icon indicating copy to clipboard operation
jmix copied to clipboard

InstanceName with reference breaks lazy loading of this reference attributes

Open knstvk opened this issue 2 months ago • 1 comments

Environment

Jmix version: 2.7.1

Bug Description

If a root entity includes a reference in its InstanceName, the reference's nested references are not loaded lazily.

Test model:

@JmixEntity
@Table(name = "ALPHA")
@Entity
public class Alpha {
    @JmixGeneratedValue
    @Column(name = "ID", nullable = false)
    @Id
    private UUID id;

    @Column(name = "NAME", nullable = false)
    @NotNull
    private String name;

    @JoinColumn(name = "BETA_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Beta beta;

    @InstanceName
    @DependsOnProperties({"name", "beta"})
    public String getInstanceName(MetadataTools metadataTools) {
        return String.format("%s - beta: %s",
                metadataTools.format(name),
                metadataTools.format(beta));
    }
}
@JmixEntity
@Table(name = "BETA")
@Entity
public class Beta {
    @JmixGeneratedValue
    @Column(name = "ID", nullable = false)
    @Id
    private UUID id;

    @InstanceName
    @Column(name = "NAME", nullable = false)
    @NotNull
    private String name;

    @JoinColumn(name = "GAMMA_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Gamma gamma;
}
@JmixEntity
@Table(name = "GAMMA")
@Entity
public class Gamma {
    @JmixGeneratedValue
    @Column(name = "ID", nullable = false)
    @Id
    private UUID id;

    @InstanceName
    @Column(name = "NAME", nullable = false)
    @NotNull
    private String name;
}

Test class:

@SpringBootTest
public class InstanceNameRefTest {

    @Autowired
    private UnconstrainedDataManager dataManager;

    @Test
    void test() {
        Gamma gamma1 = dataManager.create(Gamma.class);
        gamma1.setName("gamma1");
        gamma1 = dataManager.save(gamma1);

        Beta beta1 = dataManager.create(Beta.class);
        beta1.setName("beta1");
        beta1.setGamma(gamma1);
        beta1 = dataManager.save(beta1);

        Alpha alpha1 = dataManager.create(Alpha.class);
        alpha1.setName("alpha1");
        alpha1.setBeta(beta1);
        alpha1 = dataManager.save(alpha1);

        Alpha alpha = dataManager.load(Alpha.class).id(alpha1.getId()).one();

        // exception here
        alpha.getBeta().getGamma().getName();
    }
}

Cannot get unfetched attribute [gamma] from detached object com.company.demo.entity.Beta-019b0c3d-3edd-74cd-a088-6bfdedb2b747 [detached]. java.lang.IllegalStateException: Cannot get unfetched attribute [gamma] from detached object com.company.demo.entity.Beta-019b0c3d-3edd-74cd-a088-6bfdedb2b747 [detached]. at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.throwUnfetchedAttributeException(UnitOfWorkValueHolder.java:340) at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:126) at com.company.demo.entity.Beta._persistence_get_gamma(Beta.java) at com.company.demo.entity.Beta.getGamma(Beta.java:47) at com.company.demo.instancename.InstanceNameRefTest.test(InstanceNameRefTest.java:57)

The exception occurs because beta.gamma attribute contains org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder instead of io.jmix.eclipselink.impl.lazyloading.SingleValueOwningPropertyHolder.

knstvk avatar Dec 11 '25 07:12 knstvk

May be related to #2461

knstvk avatar Dec 11 '25 07:12 knstvk