HHH-16908 Add test for issue

This commit is contained in:
Jan Schatteman 2023-07-07 17:36:12 +02:00 committed by Christian Beikov
parent 544e9a3fb3
commit 6bc0de2a33
2 changed files with 210 additions and 0 deletions

View File

@ -0,0 +1,102 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.onetoone.bidirectional;
import java.io.Serializable;
import java.util.stream.StreamSupport;
import org.hibernate.mapping.Column;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Jan Schatteman
* @author Andrea Boriero
* @author Marco Belladelli
*/
@Jira( "https://hibernate.atlassian.net/browse/HHH-16908" )
@SessionFactory
@DomainModel( annotatedClasses = {
BidirectionalOneToOneWithIdClassesTest.Price.class,
BidirectionalOneToOneWithIdClassesTest.Product.class,
BidirectionalOneToOneWithIdClassesTest.Operator.class,
} )
public class BidirectionalOneToOneWithIdClassesTest {
@Test
public void test(SessionFactoryScope scope) {
StreamSupport.stream( scope.getMetadataImplementor().getDatabase().getNamespaces().spliterator(), false )
.flatMap( namespace -> namespace.getTables().stream() )
.forEach( t -> {
if ( t.getName().equals( "Product" ) ) {
assertThat( t.getColumns().stream().map( Column::getName ) ).contains( "productId" );
}
else if ( t.getName().equals( "Price" ) ) {
assertThat( t.getColumns().stream().map( Column::getName ) ).contains(
"operator_operatorId",
"price",
"product_productId"
);
}
} );
}
@Entity( name = "Operator" )
public static class Operator {
@Id
private String operatorId;
}
@Entity( name = "Price" )
@IdClass( PricePK.class )
public static class Price {
@Id
@ManyToOne
private Operator operator;
@Id
private String price;
@OneToOne
private Product product;
}
@Embeddable
public static class PricePK implements Serializable {
@ManyToOne
private Operator operator;
private String price;
}
@Entity( name = "Product" )
@IdClass( ProductPK.class )
public static class Product {
@Id
private String productId;
@OneToOne( mappedBy = "product" )
private Price wholesalePrice;
}
@Embeddable
public static class ProductPK implements Serializable {
private String productId;
}
}

View File

@ -0,0 +1,108 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.onetoone.bidirectional;
import java.io.Serializable;
import org.hibernate.AnnotationException;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.testing.orm.junit.Jira;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Jan Schatteman
* @author Andrea Boriero
* @author Marco Belladelli
*/
@Jira( "https://hibernate.atlassian.net/browse/HHH-16908" )
public class BidirectionalOneToOneWithIdClassesUnownedAssociationTest {
@Test
public void test() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
try {
new MetadataSources( ssr ).addAnnotatedClass( Price.class )
.addAnnotatedClass( Product.class )
.addAnnotatedClass( Operator.class )
.buildMetadata()
.getSessionFactoryBuilder()
.build();
fail( "Unowned association should not be allowed as an entity identifier" );
// See JPA spec: https://jakarta.ee/specifications/persistence/3.1/jakarta-persistence-spec-3.1.html#a149
// > The identity of an entity may be derived from the identity of another entity (the parent entity) when
// > the former entity (the dependent entity) is the owner of a many-to-one or one-to-one relationship to
// > the parent entity and a foreign key maps the relationship from dependent to parent.
}
catch (Exception e) {
assertThat( e ).isInstanceOf( AnnotationException.class );
assertThat( e.getMessage() ).contains(
"wholesalePrice' is the inverse side of a '@OneToOne' association and cannot be used as identifier"
);
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Entity( name = "Operator" )
public static class Operator {
@Id
private String operatorId;
}
@Entity( name = "Price" )
@IdClass( PricePK.class )
public static class Price {
@Id
@ManyToOne
private Operator operator;
@Id
private String price;
@OneToOne
private Product product;
}
@Embeddable
public static class PricePK implements Serializable {
@ManyToOne
private Operator operator;
private String price;
}
@Entity( name = "Product" )
@IdClass( ProductPK.class )
public static class Product {
@Id
private String productId;
@OneToOne( mappedBy = "product" )
private Price wholesalePrice;
}
@Embeddable
public static class ProductPK implements Serializable {
private String productId;
@OneToOne( mappedBy = "product" )
private Price wholesalePrice;
}
}