Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.jpa.broken;

import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.LongStream;

import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;

public class JPAUnitTestCase extends BaseEntityManagerFunctionalTestCase {


@Override
public Class<?>[] getAnnotatedClasses() {
return new Class[] {ThirdParty.class, Provider.class, VoiceGroup.class, TelephoneNumber.class};
}

@Before
public void setup() {
doInJPA( this::entityManagerFactory, em -> {

ThirdParty thirdParty = new ThirdParty();
thirdParty.setName( "Globex Corporation" );
em.persist( thirdParty );

Provider provider = new Provider();
provider.setThirdParty( thirdParty );
em.persist( provider );

VoiceGroup voiceGroup = new VoiceGroup();
em.persist( voiceGroup );

TelephoneNumber primaryNumber = new TelephoneNumber();
primaryNumber.setNumber( "4065551234" );
primaryNumber.setProvider( provider );
primaryNumber.setVoiceGroup( voiceGroup );
em.persist( primaryNumber );

voiceGroup.setPrimaryNumber( primaryNumber );

LongStream.rangeClosed( 4065551235L, 4065551255L ).forEach( value -> {
TelephoneNumber telephoneNumber = new TelephoneNumber();
telephoneNumber.setNumber( String.valueOf( value ) );
telephoneNumber.setProvider( provider );
telephoneNumber.setVoiceGroup( voiceGroup );
em.persist( telephoneNumber );
} );
} );
}

@Test
public void testThatPasses() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
VoiceGroup voiceGroup = em.find( VoiceGroup.class, 1,
Map.of( "jakarta.persistence.fetchgraph", em.getEntityGraph( "voiceGroup.graph" ) ) );
allNumbersWithThirdPartyFetch( em, voiceGroup ).forEach( telephoneNumber -> Objects.requireNonNull( telephoneNumber.getProvider().getName() ) );
em.getTransaction().commit();
em.close();
}

@Test
public void testThatFails() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
VoiceGroup voiceGroup = em.find( VoiceGroup.class, 1,
Map.of( "jakarta.persistence.fetchgraph", em.getEntityGraph( "voiceGroup.graph" ) ) );
allNumbersWithoutThirdPartyFetch( em, voiceGroup ).forEach( telephoneNumber -> Objects.requireNonNull( telephoneNumber.getProvider().getName() ) );
em.getTransaction().commit();
em.close();
}


private List<TelephoneNumber> allNumbersWithoutThirdPartyFetch(EntityManager em, VoiceGroup voiceGroup) {
CriteriaQuery<TelephoneNumber> query = em.getCriteriaBuilder().createQuery( TelephoneNumber.class );
Root<TelephoneNumber> root = query.from( TelephoneNumber.class );
root.fetch( "provider" );
query.where( em.getCriteriaBuilder().equal( root.get( "voiceGroup" ), voiceGroup ) );
return em.createQuery( query ).getResultList();
}

private List<TelephoneNumber> allNumbersWithThirdPartyFetch(EntityManager em, VoiceGroup voiceGroup) {
CriteriaQuery<TelephoneNumber> query = em.getCriteriaBuilder().createQuery( TelephoneNumber.class );
Root<TelephoneNumber> root = query.from( TelephoneNumber.class );
root.fetch( "provider" ).fetch( "thirdParty" );
query.where( em.getCriteriaBuilder().equal( root.get( "voiceGroup" ), voiceGroup ) );
return em.createQuery( query ).getResultList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.jpa.broken;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Transient;
import jakarta.persistence.Version;

import java.io.Serializable;
import java.util.Objects;

@Entity
public class Provider implements Serializable {

private Integer id;
private int version;
private ThirdParty thirdParty;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

@Version
public int getVersion() {
return version;
}

public void setVersion(int version) {
this.version = version;
}

@OneToOne(mappedBy = "provider", optional = false)
public ThirdParty getThirdParty() {
return thirdParty;
}

public void setThirdParty(ThirdParty thirdParty) {
this.thirdParty = thirdParty;
}

@Transient
public String getName() {
return thirdParty.getName();
}

@Override
public boolean equals(Object o) {
if (o instanceof Provider provider) {
return this == o || getId().equals(provider.getId());
}
else {
return false;
}
}

@Override
public int hashCode() {
return Objects.hashCode(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.jpa.broken;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Version;

import java.io.Serializable;
import java.util.Objects;

@Entity
public class TelephoneNumber implements Serializable {

private Integer id;
private int version;
private String number;
private VoiceGroup voiceGroup;
private Provider provider;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

@Version
public int getVersion() {
return version;
}

public void setVersion(int version) {
this.version = version;
}

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voiceGroup", nullable = false)
public VoiceGroup getVoiceGroup() {
return voiceGroup;
}

public void setVoiceGroup(VoiceGroup voiceGroup) {
this.voiceGroup = voiceGroup;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "provider", nullable = false)
public Provider getProvider() {
return provider;
}

public void setProvider(Provider provider) {
this.provider = provider;
}

@Override
public boolean equals(Object o) {
if ( o instanceof TelephoneNumber telephoneNumber ) {
return this == o || getId().equals( telephoneNumber.getId() );
}
else {
return false;
}
}

@Override
public int hashCode() {
return Objects.hashCode( id );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.jpa.broken;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;

import java.io.Serializable;

@Entity
public class ThirdParty implements Serializable {

private Integer id;
private int version;
private String name;
private Provider provider;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

@Version
public int getVersion() {
return version;
}

public void setVersion(int version) {
this.version = version;
}

@NotNull
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "provider", nullable = true)
public Provider getProvider() {
return provider;
}

public void setProvider(Provider provider) {
this.provider = provider;
}
}
Loading
Loading