diff --git a/src/main/java/org/springframework/data/jdbc/mapping/context/JdbcMappingContext.java b/src/main/java/org/springframework/data/jdbc/mapping/context/JdbcMappingContext.java index 469a0eeb..9d228ce7 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/context/JdbcMappingContext.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/context/JdbcMappingContext.java @@ -16,31 +16,38 @@ package org.springframework.data.jdbc.mapping.context; import org.springframework.data.jdbc.mapping.model.BasicJdbcPersistentProperty; -import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntityImpl; import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; import org.springframework.data.mapping.context.AbstractMappingContext; +import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; /** + * {@link MappingContext} implementation for JDBC. + * * @author Jens Schauder * @since 2.0 */ -public class JdbcMappingContext extends AbstractMappingContext, JdbcPersistentProperty> { +public class JdbcMappingContext extends AbstractMappingContext, JdbcPersistentProperty> { + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation) + */ @Override - protected JdbcPersistentEntity createPersistentEntity(TypeInformation typeInformation) { - return new JdbcPersistentEntity(typeInformation); + protected JdbcPersistentEntityImpl createPersistentEntity(TypeInformation typeInformation) { + return new JdbcPersistentEntityImpl<>(typeInformation); } + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(org.springframework.data.mapping.model.Property, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder) + */ @Override - protected JdbcPersistentProperty createPersistentProperty( // - Property property, // - JdbcPersistentEntity owner, // - SimpleTypeHolder simpleTypeHolder // - ) { + protected JdbcPersistentProperty createPersistentProperty(Property property, JdbcPersistentEntityImpl owner, + SimpleTypeHolder simpleTypeHolder) { return new BasicJdbcPersistentProperty(property, owner, simpleTypeHolder); } - } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterCreation.java b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterCreation.java index abdf582e..b0f2e8ed 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterCreation.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterCreation.java @@ -26,6 +26,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class AfterCreation extends JdbcEventWithIdAndEntity { + private static final long serialVersionUID = -4185777271143436728L; + /** * @param id of the entity * @param entity the newly instantiated entity. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterDelete.java b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterDelete.java index 4ebca774..f1f24d19 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterDelete.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterDelete.java @@ -28,6 +28,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class AfterDelete extends JdbcEventWithId { + private static final long serialVersionUID = 3594807189931141582L; + /** * @param id of the entity. * @param instance the deleted entity if it is available. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterInsert.java b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterInsert.java index 9a6f4145..5b82bd3c 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterInsert.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterInsert.java @@ -25,6 +25,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class AfterInsert extends AfterSave { + private static final long serialVersionUID = 1312645717283677063L; + /** * @param id identifier of the entity triggering the event. * @param instance the newly inserted entity. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterSave.java b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterSave.java index c83d48dd..9c79e213 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterSave.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterSave.java @@ -25,6 +25,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class AfterSave extends JdbcEventWithIdAndEntity { + private static final long serialVersionUID = 8982085767296982848L; + /** * @param id identifier of * @param instance the newly saved entity. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterUpdate.java b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterUpdate.java index b95cd093..cda83304 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/AfterUpdate.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/AfterUpdate.java @@ -25,6 +25,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class AfterUpdate extends AfterSave { + private static final long serialVersionUID = -1765706904721563399L; + /** * @param id of the entity * @param instance the updated entity. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeDelete.java b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeDelete.java index 4d221b2e..ef7d1c0f 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeDelete.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeDelete.java @@ -27,6 +27,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class BeforeDelete extends JdbcEventWithId { + private static final long serialVersionUID = -5483432053368496651L; + /** * @param id the id of the entity * @param entity the entity about to get deleted. Might be empty. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeInsert.java b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeInsert.java index dcd669dd..37d22270 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeInsert.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeInsert.java @@ -15,8 +15,6 @@ */ package org.springframework.data.jdbc.mapping.event; -import org.springframework.data.jdbc.mapping.event.Identifier.Unset; - /** * Gets published before an entity gets inserted into the database. When the id-property of the entity must get set * manually, an event listener for this event may do so.
@@ -27,6 +25,8 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Unset; */ public class BeforeInsert extends BeforeSave { + private static final long serialVersionUID = -5350552051337308870L; + /** * @param instance the entity about to get inserted. */ diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeSave.java b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeSave.java index b6eeb701..ae100d39 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeSave.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeSave.java @@ -23,6 +23,8 @@ package org.springframework.data.jdbc.mapping.event; */ public class BeforeSave extends JdbcEventWithEntity { + private static final long serialVersionUID = -6996874391990315443L; + /** * @param id of the entity to be saved. * @param instance the entity about to get saved. diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeUpdate.java b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeUpdate.java index 72ad695d..57f7a330 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeUpdate.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/BeforeUpdate.java @@ -25,11 +25,27 @@ import org.springframework.data.jdbc.mapping.event.Identifier.Specified; */ public class BeforeUpdate extends BeforeSave implements WithId { + private static final long serialVersionUID = 794561215071613972L; + + private final Specified id; + /** * @param id of the entity about to get updated * @param instance the entity about to get updated. */ public BeforeUpdate(Specified id, Object instance) { + super(id, instance); + + this.id = id; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.JdbcEvent#getId() + */ + @Override + public Specified getId() { + return id; } } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/Identifier.java b/src/main/java/org/springframework/data/jdbc/mapping/event/Identifier.java index 43eb3566..0db46646 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/Identifier.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/Identifier.java @@ -15,11 +15,10 @@ */ package org.springframework.data.jdbc.mapping.event; -import lombok.Data; -import lombok.NonNull; - import java.util.Optional; +import org.springframework.util.Assert; + /** * Wrapper for an identifier of an entity. Might either be a {@link Specified} or {@link Unset#UNSET} * @@ -28,36 +27,53 @@ import java.util.Optional; */ public interface Identifier { - static Identifier fromNullable(Object value) { - return (value != null) ? new Specified(value) : Unset.UNSET; - } - - Optional getOptionalValue(); - /** - * An unset identifier. Always returns {@link Optional#empty()} as value. + * Creates a new {@link Specified} identifier for the given, non-null value. + * + * @param identifier must not be {@literal null}. + * @return will never be {@literal null}. */ - enum Unset implements Identifier { - UNSET { - @Override - public Optional getOptionalValue() { - return Optional.empty(); - } - } + static Specified of(Object identifier) { + + Assert.notNull(identifier, "Identifier must not be null!"); + + return SpecifiedIdentifier.of(identifier); } /** - * An {@link Identifier} guaranteed to have a non empty value. Since it is guaranteed to exist the value can get - * access directly. + * Creates a new {@link Identifier} for the given optional source value. + * + * @param identifier must not be {@literal null}. + * @return */ - @Data - class Specified implements Identifier { + static Identifier of(Optional identifier) { - @NonNull private final Object value; + Assert.notNull(identifier, "Identifier must not be null!"); - @Override - public Optional getOptionalValue() { - return Optional.of(value); + return identifier.map(it -> (Identifier) Identifier.of(it)).orElse(Unset.UNSET); + } + + /** + * Returns the identifier value. + * + * @return will never be {@literal null}. + */ + Optional getOptionalValue(); + + /** + * A specified identifier that exposes a definitely present identifier value. + * + * @author Oliver Gierke + */ + interface Specified extends Identifier { + + /** + * Returns the identifier value. + * + * @return will never be {@literal null}. + */ + default Object getValue() { + return getOptionalValue().orElseThrow(() -> new IllegalStateException("Should not happen!")); } } } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEvent.java b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEvent.java index 9c233969..d862517a 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEvent.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEvent.java @@ -15,40 +15,26 @@ */ package org.springframework.data.jdbc.mapping.event; -import lombok.Getter; - import java.util.Optional; -import org.springframework.context.ApplicationEvent; - /** - * The common superclass for all events published by JDBC repositories. {@link #getSource} contains the - * {@link Identifier} of the entity triggering the event. * - * @author Jens Schauder - * @since 2.0 + * @author Oliver Gierke */ -@Getter -public class JdbcEvent extends ApplicationEvent { - - /** - * The optional entity for which this event was published. Might be empty in cases of delete events where only the - * identifier was passed to the delete method. - */ - private final Optional optionalEntity; - - JdbcEvent(Identifier id, Optional optionalEntity) { - super(id); - this.optionalEntity = optionalEntity; - } +public interface JdbcEvent { /** * The identifier of the entity, triggering this event. Also available via {@link #getSource()}. * * @return the source of the event as an {@link Identifier}. */ - public Identifier getId() { - return (Identifier) getSource(); - } + Identifier getId(); + + /** + * Returns the entity the event was triggered for. + * + * @return will never be {@literal null}. + */ + Optional getOptionalEntity(); } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithEntity.java b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithEntity.java index c103dd6e..1d325f6b 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithEntity.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithEntity.java @@ -18,12 +18,14 @@ package org.springframework.data.jdbc.mapping.event; import java.util.Optional; /** - * A {@link JdbcEvent} which is guaranteed to have an entity. + * A {@link SimpleJdbcEvent} which is guaranteed to have an entity. * * @author Jens Schauder * @since 2.0 */ -public class JdbcEventWithEntity extends JdbcEvent implements WithEntity { +public class JdbcEventWithEntity extends SimpleJdbcEvent implements WithEntity { + + private static final long serialVersionUID = 4891455396602090638L; public JdbcEventWithEntity(Identifier id, Object entity) { super(id, Optional.of(entity)); diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithId.java b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithId.java index 5622672e..d5c1ded0 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithId.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithId.java @@ -20,14 +20,30 @@ import java.util.Optional; import org.springframework.data.jdbc.mapping.event.Identifier.Specified; /** - * A {@link JdbcEvent} guaranteed to have an identifier. + * A {@link SimpleJdbcEvent} guaranteed to have an identifier. * * @author Jens Schauder * @since 2.0 */ -public class JdbcEventWithId extends JdbcEvent implements WithId { +public class JdbcEventWithId extends SimpleJdbcEvent implements WithId { + + private static final long serialVersionUID = -8071323168471611098L; + + private final Specified id; public JdbcEventWithId(Specified id, Optional entity) { + super(id, entity); + + this.id = id; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.JdbcEvent#getId() + */ + @Override + public Specified getId() { + return id; } } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithIdAndEntity.java b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithIdAndEntity.java index 819ef896..e9268bf4 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithIdAndEntity.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/JdbcEventWithIdAndEntity.java @@ -22,13 +22,15 @@ import java.util.Optional; import org.springframework.data.jdbc.mapping.event.Identifier.Specified; /** - * A {@link JdbcEvent} which is guaranteed to have an identifier and an entity. + * A {@link SimpleJdbcEvent} which is guaranteed to have an identifier and an entity. * * @author Jens Schauder * @since 2.0 */ @Getter -public class JdbcEventWithIdAndEntity extends JdbcEvent implements WithId, WithEntity { +public class JdbcEventWithIdAndEntity extends JdbcEventWithId implements WithEntity { + + private static final long serialVersionUID = -3194462549552515519L; public JdbcEventWithIdAndEntity(Specified id, Object entity) { super(id, Optional.of(entity)); diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/SimpleJdbcEvent.java b/src/main/java/org/springframework/data/jdbc/mapping/event/SimpleJdbcEvent.java new file mode 100644 index 00000000..bf5df81a --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/SimpleJdbcEvent.java @@ -0,0 +1,60 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.mapping.event; + +import java.util.Optional; + +import org.springframework.context.ApplicationEvent; + +/** + * The common superclass for all events published by JDBC repositories. {@link #getSource} contains the + * {@link Identifier} of the entity triggering the event. + * + * @author Jens Schauder + * @author Oliver Gierke + * @since 2.0 + */ +class SimpleJdbcEvent extends ApplicationEvent implements JdbcEvent { + + private static final long serialVersionUID = -1798807778668751659L; + + private final Object entity; + + SimpleJdbcEvent(Identifier id, Optional entity) { + + super(id); + + this.entity = entity.orElse(null); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.JdbcEvent#getId() + */ + @Override + public Identifier getId() { + return (Identifier) getSource(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.JdbcEvent#getOptionalEntity() + */ + @Override + public Optional getOptionalEntity() { + return Optional.ofNullable(entity); + } +} diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/SpecifiedIdentifier.java b/src/main/java/org/springframework/data/jdbc/mapping/event/SpecifiedIdentifier.java new file mode 100644 index 00000000..a68c97b2 --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/SpecifiedIdentifier.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.mapping.event; + +import lombok.Value; + +import java.util.Optional; + +import org.springframework.data.jdbc.mapping.event.Identifier.Specified; + +/** + * Simple value object for {@link Specified}. + * + * @author Jens Schauder + * @author Oliver Gierke + * @since 2.0 + */ +@Value(staticConstructor = "of") +class SpecifiedIdentifier implements Specified { + + Object value; + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.Identifier#getOptionalValue() + */ + @Override + public Optional getOptionalValue() { + return Optional.of(value); + } +} diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/Unset.java b/src/main/java/org/springframework/data/jdbc/mapping/event/Unset.java new file mode 100644 index 00000000..0fd30e40 --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/Unset.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.mapping.event; + +import java.util.Optional; + +/** + * An unset identifier. Always returns {@link Optional#empty()} as value. + * + * @author Jens Schaude + * @author Oliver Gierke + * @since 2.0 + */ +enum Unset implements Identifier { + + UNSET; + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.event.Identifier#getOptionalValue() + */ + @Override + public Optional getOptionalValue() { + return Optional.empty(); + } +} diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/WithEntity.java b/src/main/java/org/springframework/data/jdbc/mapping/event/WithEntity.java index 8e4687ee..568a8437 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/WithEntity.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/WithEntity.java @@ -16,16 +16,18 @@ package org.springframework.data.jdbc.mapping.event; /** - * Interface for {@link JdbcEvent}s which are guaranteed to have an entity. Allows direct access to that entity, without - * going through an {@link java.util.Optional} + * Interface for {@link SimpleJdbcEvent}s which are guaranteed to have an entity. Allows direct access to that entity, + * without going through an {@link java.util.Optional} * * @author Jens Schauder * @since 2.0 */ -public interface WithEntity { +public interface WithEntity extends JdbcEvent { + /** + * @return will never be {@literal null}. + */ default Object getEntity() { - return ((JdbcEvent) this).getOptionalEntity() - .orElseThrow(() -> new IllegalStateException("Entity must not be NULL")); + return getOptionalEntity().orElseThrow(() -> new IllegalStateException("Entity must not be NULL")); } } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/event/WithId.java b/src/main/java/org/springframework/data/jdbc/mapping/event/WithId.java index d6b5fcf1..f5c857dc 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/event/WithId.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/event/WithId.java @@ -18,15 +18,16 @@ package org.springframework.data.jdbc.mapping.event; import org.springframework.data.jdbc.mapping.event.Identifier.Specified; /** - * Interface for {@link JdbcEvent}s which are guaranteed to have a {@link Specified} identifier. Offers direct access to - * the {@link Specified} identifier. + * Interface for {@link SimpleJdbcEvent}s which are guaranteed to have a {@link Specified} identifier. Offers direct + * access to the {@link Specified} identifier. * * @author Jens Schauder * @since 2.0 */ -public interface WithId { +public interface WithId extends JdbcEvent { - default Specified getSpecifiedId() { - return (Specified) ((JdbcEvent) this).getId(); - } + /** + * Events with an identifier will always return a {@link Specified} one. + */ + Specified getId(); } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentProperty.java b/src/main/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentProperty.java index 64f6126e..cda28019 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentProperty.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentProperty.java @@ -35,21 +35,26 @@ public class BasicJdbcPersistentProperty extends AnnotationBasedPersistentProper * * @param property must not be {@literal null}. * @param owner must not be {@literal null}. - * @param simpleTypeHolder + * @param simpleTypeHolder must not be {@literal null}. */ - public BasicJdbcPersistentProperty( // - Property property, // - PersistentEntity owner, // - SimpleTypeHolder simpleTypeHolder // - ) { + public BasicJdbcPersistentProperty(Property property, PersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { super(property, owner, simpleTypeHolder); } + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation() + */ @Override protected Association createAssociation() { - return null; + throw new UnsupportedOperationException(); } + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty#getColumnName() + */ public String getColumnName() { return getName(); } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java index 3102cfde..ee7a75d3 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java @@ -15,31 +15,26 @@ */ package org.springframework.data.jdbc.mapping.model; -import org.springframework.data.mapping.model.BasicPersistentEntity; -import org.springframework.data.util.TypeInformation; +import org.springframework.data.mapping.PersistentEntity; /** - * Meta data a repository might need for implementing persistence operations for instances of type {@code T} - * * @author Jens Schauder + * @author Oliver Gierke * @since 2.0 */ -public class JdbcPersistentEntity extends BasicPersistentEntity { +public interface JdbcPersistentEntity extends PersistentEntity { - private final String tableName; + /** + * Returns the name of the table backing the given entity. + * + * @return + */ + String getTableName(); - public JdbcPersistentEntity(TypeInformation information) { - - super(information); - - tableName = getType().getSimpleName(); - } - - public String getTableName() { - return tableName; - } - - public String getIdColumn() { - return getRequiredIdProperty().getName(); - } + /** + * Returns the column representing the identifier. + * + * @return will never be {@literal null}. + */ + String getIdColumn(); } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntityImpl.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntityImpl.java new file mode 100644 index 00000000..744423f1 --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntityImpl.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.mapping.model; + +import lombok.Getter; + +import org.springframework.data.mapping.model.BasicPersistentEntity; +import org.springframework.data.util.TypeInformation; + +/** + * Meta data a repository might need for implementing persistence operations for instances of type {@code T} + * + * @author Jens Schauder + * @since 2.0 + */ +public class JdbcPersistentEntityImpl extends BasicPersistentEntity + implements JdbcPersistentEntity { + + private final @Getter String tableName; + + /** + * Creates a new {@link JdbcPersistentEntityImpl} for the given {@link TypeInformation}. + * + * @param information must not be {@literal null}. + */ + public JdbcPersistentEntityImpl(TypeInformation information) { + + super(information); + + tableName = getType().getSimpleName(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity#getIdColumn() + */ + @Override + public String getIdColumn() { + return getRequiredIdProperty().getName(); + } +} diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java index e63cd4fa..7a8ffc63 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java @@ -18,10 +18,18 @@ package org.springframework.data.jdbc.mapping.model; import org.springframework.data.mapping.PersistentProperty; /** + * A {@link PersistentProperty} for JDBC. + * * @author Jens Schauder + * @author Oliver Gierke * @since 2.0 */ public interface JdbcPersistentProperty extends PersistentProperty { + /** + * Returns the name of the column backing that property. + * + * @return + */ String getColumnName(); } diff --git a/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java b/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java index e94af8ca..b529d918 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java +++ b/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jdbc.repository; +import lombok.RequiredArgsConstructor; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; @@ -26,8 +28,10 @@ import org.springframework.data.convert.EntityInstantiator; import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor.Parameter; import org.springframework.data.mapping.PropertyHandler; +import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.ParameterValueProvider; import org.springframework.jdbc.core.RowMapper; @@ -36,65 +40,68 @@ import org.springframework.jdbc.core.RowMapper; * Maps a ResultSet to an entity of type {@code T} * * @author Jens Schauder + * @author Oliver Gierke * @since 2.0 */ +@RequiredArgsConstructor class EntityRowMapper implements RowMapper { private final JdbcPersistentEntity entity; private final EntityInstantiator instantiator = new ClassGeneratingEntityInstantiator(); private final ConversionService conversions = new DefaultConversionService(); - EntityRowMapper(JdbcPersistentEntity entity) { - this.entity = entity; - } - + /* + * (non-Javadoc) + * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) + */ @Override - public T mapRow(ResultSet rs, int rowNum) throws SQLException { + public T mapRow(ResultSet resultSet, int rowNumber) throws SQLException { - T t = createInstance(rs); + T result = createInstance(resultSet); entity.doWithProperties((PropertyHandler) property -> { - setProperty(rs, t, property); + + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(result); + ConvertingPropertyAccessor propertyAccessor = new ConvertingPropertyAccessor(accessor, conversions); + + propertyAccessor.setProperty(property, readFrom(resultSet, property)); }); - return t; + return result; } private T createInstance(ResultSet rs) { - - return instantiator.createInstance(entity, new ResultSetParameterValueProvider(rs)); + return instantiator.createInstance(entity, ResultSetParameterValueProvider.of(rs, conversions)); } - private void setProperty(ResultSet rs, T t, PersistentProperty property) { + private static Optional readFrom(ResultSet resultSet, PersistentProperty property) { try { - - Object converted = conversions.convert(rs.getObject(property.getName()), property.getType()); - entity.getPropertyAccessor(t).setProperty(property, Optional.of(converted)); - } catch (Exception e) { - throw new RuntimeException(String.format("Couldn't set property %s.", property.getName()), e); + return Optional.ofNullable(resultSet.getObject(property.getName())); + } catch (SQLException o_O) { + throw new MappingException(String.format("Could not read property %s from result set!", property), o_O); } } - private class ResultSetParameterValueProvider implements ParameterValueProvider { + @RequiredArgsConstructor(staticName = "of") + private static class ResultSetParameterValueProvider implements ParameterValueProvider { - private final ResultSet rs; - - ResultSetParameterValueProvider(ResultSet rs) { - this.rs = rs; - } + private final ResultSet resultSet; + private final ConversionService conversionService; + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter) + */ @Override public Optional getParameterValue(Parameter parameter) { return parameter.getName().map(name -> { - try { - return conversions.convert(rs.getObject(name), parameter.getType().getType()); - } catch (SQLException e) { - throw new MappingException( // - String.format("Couldn't read column %s from ResultSet.", name) // - ); + try { + return conversionService.convert(resultSet.getObject(name), parameter.getType().getType()); + } catch (SQLException o_O) { + throw new MappingException(String.format("Couldn't read column %s from ResultSet.", name), o_O); } }); } diff --git a/src/main/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapper.java b/src/main/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapper.java index 9eca27da..24723ff0 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapper.java +++ b/src/main/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapper.java @@ -15,15 +15,15 @@ */ package org.springframework.data.jdbc.repository; +import lombok.NonNull; import lombok.RequiredArgsConstructor; -import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.jdbc.mapping.event.AfterCreation; -import org.springframework.data.jdbc.mapping.event.Identifier.Specified; +import org.springframework.data.jdbc.mapping.event.Identifier; import org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInformation; import org.springframework.jdbc.core.RowMapper; @@ -35,18 +35,22 @@ import org.springframework.jdbc.core.RowMapper; * @since 2.0 */ @RequiredArgsConstructor -public class EventPublishingEntityRowMapper implements RowMapper { +public class EventPublishingEntityRowMapper implements RowMapper { - private final RowMapper delegate; - private final JdbcPersistentEntityInformation entityInformation; - private final ApplicationEventPublisher publisher; + private final @NonNull RowMapper delegate; + private final @NonNull JdbcPersistentEntityInformation entityInformation; + private final @NonNull ApplicationEventPublisher publisher; + /* + * (non-Javadoc) + * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) + */ @Override public T mapRow(ResultSet resultSet, int i) throws SQLException { T instance = delegate.mapRow(resultSet, i); - publisher.publishEvent(new AfterCreation(new Specified(entityInformation.getId(instance)), instance)); + publisher.publishEvent(new AfterCreation(Identifier.of(entityInformation.getRequiredId(instance)), instance)); return instance; } diff --git a/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java b/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java index e6109cea..1f585a32 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java +++ b/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.convert.ConversionService; @@ -35,13 +34,16 @@ import org.springframework.data.jdbc.mapping.event.AfterUpdate; import org.springframework.data.jdbc.mapping.event.BeforeDelete; import org.springframework.data.jdbc.mapping.event.BeforeInsert; import org.springframework.data.jdbc.mapping.event.BeforeUpdate; +import org.springframework.data.jdbc.mapping.event.Identifier; import org.springframework.data.jdbc.mapping.event.Identifier.Specified; import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntityImpl; import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; import org.springframework.data.jdbc.repository.support.BasicJdbcPersistentEntityInformation; import org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInformation; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.util.Streamable; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -66,11 +68,15 @@ public class SimpleJdbcRepository implements CrudRep private final ApplicationEventPublisher publisher; private final ConversionService conversions = new DefaultConversionService(); - public SimpleJdbcRepository( // - JdbcPersistentEntity persistentEntity, // - NamedParameterJdbcOperations jdbcOperations, // - ApplicationEventPublisher publisher // - ) { + /** + * Creates a new {@link SimpleJdbcRepository} for the given {@link JdbcPersistentEntityImpl} + * + * @param persistentEntity + * @param jdbcOperations + * @param publisher + */ + public SimpleJdbcRepository(JdbcPersistentEntity persistentEntity, NamedParameterJdbcOperations jdbcOperations, + ApplicationEventPublisher publisher) { Assert.notNull(persistentEntity, "PersistentEntity must not be null."); Assert.notNull(jdbcOperations, "JdbcOperations must not be null."); @@ -85,6 +91,10 @@ public class SimpleJdbcRepository implements CrudRep this.sql = new SqlGenerator(persistentEntity); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#save(S) + */ @Override public S save(S instance) { @@ -97,6 +107,10 @@ public class SimpleJdbcRepository implements CrudRep return instance; } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable) + */ @Override public Iterable save(Iterable entities) { @@ -105,6 +119,10 @@ public class SimpleJdbcRepository implements CrudRep return savedEntities; } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable) + */ @Override public Optional findOne(ID id) { @@ -112,43 +130,69 @@ public class SimpleJdbcRepository implements CrudRep .ofNullable(operations.queryForObject(sql.getFindOne(), new MapSqlParameterSource("id", id), entityRowMapper)); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable) + */ @Override public boolean exists(ID id) { - return operations.queryForObject(sql.getExists(), new MapSqlParameterSource("id", id), Boolean.class); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#findAll() + */ @Override public Iterable findAll() { return operations.query(sql.getFindAll(), entityRowMapper); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable) + */ @Override public Iterable findAll(Iterable ids) { return operations.query(sql.getFindAllInList(), new MapSqlParameterSource("ids", ids), entityRowMapper); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#count() + */ @Override public long count() { return operations.getJdbcOperations().queryForObject(sql.getCount(), Long.class); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable) + */ @Override public void delete(ID id) { - doDelete(new Specified(id), Optional.empty()); + doDelete(Identifier.of(id), Optional.empty()); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object) + */ @Override public void delete(T instance) { - doDelete(new Specified(entityInformation.getId(instance).orElse(null)), Optional.of(instance)); + doDelete(Identifier.of(entityInformation.getRequiredId(instance)), Optional.of(instance)); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable) + */ @Override public void delete(Iterable entities) { - List idList = StreamSupport.stream(entities.spliterator(), false) // - .map(e -> entityInformation.getId(e) - .orElseThrow(() -> new IllegalArgumentException(String.format("Can't obtain id for %s", e)))) // + List idList = Streamable.of(entities).stream() // + .map(e -> entityInformation.getRequiredId(e)) // .collect(Collectors.toList()); MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource("ids", idList); @@ -189,7 +233,7 @@ public class SimpleJdbcRepository implements CrudRep throw new IllegalStateException(String.format(ENTITY_NEW_AFTER_INSERT, persistentEntity)); } - publisher.publishEvent(new AfterInsert(new Specified(entityInformation.getId(instance)), instance)); + publisher.publishEvent(new AfterInsert(Identifier.of(entityInformation.getRequiredId(instance)), instance)); } private ID getIdValueOrNull(S instance) { @@ -211,27 +255,26 @@ public class SimpleJdbcRepository implements CrudRep try { - Object idValueFromJdbc = getIdFromHolder(holder); - if (idValueFromJdbc != null) { + getIdFromHolder(holder).ifPresent(it -> { Class targetType = persistentEntity.getRequiredIdProperty().getType(); - Object converted = convert(idValueFromJdbc, targetType); + Object converted = convert(it, targetType); entityInformation.setId(instance, Optional.of(converted)); - } + }); } catch (NonTransientDataAccessException e) { - throw new UnableToSetIdException("Unable to set id of " + instance, e); + throw new UnableToSetId("Unable to set id of " + instance, e); } } - private Object getIdFromHolder(KeyHolder holder) { + private Optional getIdFromHolder(KeyHolder holder) { try { - // mysql just returns one value with a special name - return holder.getKey(); + // MySQL just returns one value with a special name + return Optional.ofNullable(holder.getKey()); } catch (InvalidDataAccessApiUsageException e) { - // postgress returns a value for each column - return holder.getKeys().get(persistentEntity.getIdColumn()); + // Postgres returns a value for each column + return Optional.ofNullable(holder.getKeys().get(persistentEntity.getIdColumn())); } } @@ -249,7 +292,7 @@ public class SimpleJdbcRepository implements CrudRep private void doUpdate(S instance) { - Specified specifiedId = new Specified(entityInformation.getId(instance)); + Specified specifiedId = Identifier.of(entityInformation.getRequiredId(instance)); publisher.publishEvent(new BeforeUpdate(specifiedId, instance)); operations.update(sql.getUpdate(), getPropertyMap(instance)); publisher.publishEvent(new AfterUpdate(specifiedId, instance)); diff --git a/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java b/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java index a67bdd88..89ad5918 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java +++ b/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java @@ -51,6 +51,7 @@ class SqlGenerator { private final List nonIdPropertyNames = new ArrayList<>(); SqlGenerator(JdbcPersistentEntity entity) { + this.entity = entity; initPropertyNames(); @@ -72,6 +73,7 @@ class SqlGenerator { } private void initPropertyNames() { + entity.doWithProperties((PropertyHandler) p -> { propertyNames.add(p.getName()); if (!entity.isIdProperty(p)) { @@ -143,8 +145,7 @@ class SqlGenerator { private String createInsertSql() { String insertTemplate = "insert into %s (%s) values (%s)"; - - String tableColumns = nonIdPropertyNames.stream().collect(Collectors.joining(", ")); + String tableColumns = String.join(", ", nonIdPropertyNames); String parameterNames = nonIdPropertyNames.stream().collect(Collectors.joining(", :", ":", "")); return String.format(insertTemplate, entity.getTableName(), tableColumns, parameterNames); @@ -154,7 +155,8 @@ class SqlGenerator { String updateTemplate = "update %s set %s where %s = :%s"; - String setClause = propertyNames.stream().map(n -> String.format("%s = :%s", n, n)) + String setClause = propertyNames.stream()// + .map(n -> String.format("%s = :%s", n, n))// .collect(Collectors.joining(", ")); return String.format(updateTemplate, entity.getTableName(), setClause, entity.getIdColumn(), entity.getIdColumn()); diff --git a/src/main/java/org/springframework/data/jdbc/repository/UnableToSetIdException.java b/src/main/java/org/springframework/data/jdbc/repository/UnableToSetId.java similarity index 81% rename from src/main/java/org/springframework/data/jdbc/repository/UnableToSetIdException.java rename to src/main/java/org/springframework/data/jdbc/repository/UnableToSetId.java index 1bbb0126..e6e22c1b 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/UnableToSetIdException.java +++ b/src/main/java/org/springframework/data/jdbc/repository/UnableToSetId.java @@ -23,9 +23,11 @@ import org.springframework.dao.NonTransientDataAccessException; * @author Jens Schauder * @since 2.0 */ -public class UnableToSetIdException extends NonTransientDataAccessException { +public class UnableToSetId extends NonTransientDataAccessException { - public UnableToSetIdException(String message, Throwable cause) { + private static final long serialVersionUID = 3285001352389420376L; + + public UnableToSetId(String message, Throwable cause) { super(message, cause); } } diff --git a/src/main/java/org/springframework/data/jdbc/repository/support/BasicJdbcPersistentEntityInformation.java b/src/main/java/org/springframework/data/jdbc/repository/support/BasicJdbcPersistentEntityInformation.java index 04178886..7ac1539e 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/support/BasicJdbcPersistentEntityInformation.java +++ b/src/main/java/org/springframework/data/jdbc/repository/support/BasicJdbcPersistentEntityInformation.java @@ -31,11 +31,16 @@ public class BasicJdbcPersistentEntityInformation ex private final JdbcPersistentEntity persistentEntity; public BasicJdbcPersistentEntityInformation(JdbcPersistentEntity persistentEntity) { + super(persistentEntity); this.persistentEntity = persistentEntity; } + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInformation#setId(java.lang.Object, java.util.Optional) + */ @Override public void setId(T instance, Optional value) { persistentEntity.getPropertyAccessor(instance).setProperty(persistentEntity.getRequiredIdProperty(), value); diff --git a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcPersistentEntityInformation.java b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcPersistentEntityInformation.java index 62227faf..78ccae92 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcPersistentEntityInformation.java +++ b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcPersistentEntityInformation.java @@ -27,4 +27,16 @@ import org.springframework.data.repository.core.EntityInformation; public interface JdbcPersistentEntityInformation extends EntityInformation { void setId(T instance, Optional value); + + /** + * Returns the identifier of the given entity or throws and exception if it can't be obtained. + * + * @param entity must not be {@literal null}. + * @return the identifier of the given entity + * @throws IllegalArgumentException in case no identifier can be obtained for the given entity. + */ + default ID getRequiredId(T entity) { + return getId(entity).orElseThrow(() -> new IllegalArgumentException( + String.format("Could not obtain required identifier from entity %s!", entity))); + } } diff --git a/src/test/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapperTest.java b/src/test/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapperTest.java index 3f521eb9..fe6f94ba 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapperTest.java +++ b/src/test/java/org/springframework/data/jdbc/repository/EventPublishingEntityRowMapperTest.java @@ -1,14 +1,33 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.jdbc.repository; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import lombok.Data; +import lombok.Value; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.annotation.Id; import org.springframework.data.jdbc.mapping.event.AfterCreation; @@ -16,13 +35,17 @@ import org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInfo import org.springframework.jdbc.core.RowMapper; /** + * Unit tests for {@link EventPublishingEntityRowMapper}. + * * @author Jens Schauder + * @author Oliver Gierke */ +@RunWith(MockitoJUnitRunner.class) public class EventPublishingEntityRowMapperTest { - RowMapper rowMapperDelegate = mock(RowMapper.class); - JdbcPersistentEntityInformation entityInformation = mock(JdbcPersistentEntityInformation.class); - ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class); + @Mock RowMapper rowMapperDelegate; + @Mock JdbcPersistentEntityInformation entityInformation; + @Mock ApplicationEventPublisher publisher; @Test // DATAJDBC-99 public void eventGetsPublishedAfterInstantiation() throws SQLException { @@ -30,10 +53,8 @@ public class EventPublishingEntityRowMapperTest { when(rowMapperDelegate.mapRow(any(ResultSet.class), anyInt())).thenReturn(new DummyEntity(1L)); when(entityInformation.getId(any())).thenReturn(Optional.of(1L)); - EventPublishingEntityRowMapper rowMapper = new EventPublishingEntityRowMapper<>( // - rowMapperDelegate, // - entityInformation, // - publisher); + EventPublishingEntityRowMapper rowMapper = new EventPublishingEntityRowMapper<>(rowMapperDelegate, + entityInformation, publisher); ResultSet resultSet = mock(ResultSet.class); rowMapper.mapRow(resultSet, 1); @@ -41,8 +62,8 @@ public class EventPublishingEntityRowMapperTest { verify(publisher).publishEvent(isA(AfterCreation.class)); } - @Data + @Value static class DummyEntity { - @Id private final Long Id; + @Id Long Id; } } diff --git a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java index 1d289b77..a615a1eb 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java @@ -15,27 +15,21 @@ */ package org.springframework.data.jdbc.repository; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.*; import lombok.Data; - -import java.util.Optional; - -import javax.sql.DataSource; +import lombok.Value; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; -import org.springframework.data.jdbc.repository.JdbcRepositoryIdGenerationIntegrationTests.TestConfiguration; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.repository.CrudRepository; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.test.context.ContextConfiguration; @@ -47,9 +41,31 @@ import org.springframework.test.context.junit4.rules.SpringMethodRule; * * @author Jens Schauder */ -@ContextConfiguration(classes = TestConfiguration.class) +@ContextConfiguration public class JdbcRepositoryIdGenerationIntegrationTests { + @Configuration + @Import(TestConfiguration.class) + static class Config { + + @Autowired JdbcRepositoryFactory factory; + + @Bean + Class testClass() { + return JdbcRepositoryIdGenerationIntegrationTests.class; + } + + @Bean + ReadOnlyIdEntityRepository readOnlyIdRepository() { + return factory.getRepository(ReadOnlyIdEntityRepository.class); + } + + @Bean + PrimitiveIdEntityRepository primitiveIdRepository() { + return factory.getRepository(PrimitiveIdEntityRepository.class); + } + } + @ClassRule public static final SpringClassRule classRule = new SpringClassRule(); @Rule public SpringMethodRule methodRule = new SpringMethodRule(); @@ -60,17 +76,15 @@ public class JdbcRepositoryIdGenerationIntegrationTests { @Test // DATAJDBC-98 public void idWithoutSetterGetsSet() { - ReadOnlyIdEntity entity = new ReadOnlyIdEntity(null); - entity.setName("Entity Name"); - entity = readOnlyIdrepository.save(entity); + ReadOnlyIdEntity entity = readOnlyIdrepository.save(new ReadOnlyIdEntity(null, "Entity Name")); assertThat(entity.getId()).isNotNull(); - Optional reloadedEntity = readOnlyIdrepository.findOne(entity.getId()); + assertThat(readOnlyIdrepository.findOne(entity.getId())).hasValueSatisfying(it -> { - assertTrue(reloadedEntity.isPresent()); - assertEquals(entity.getId(), reloadedEntity.get().getId()); - assertEquals(entity.getName(), reloadedEntity.get().getName()); + assertThat(it.getId()).isEqualTo(entity.getId()); + assertThat(it.getName()).isEqualTo(entity.getName()); + }); } @Test // DATAJDBC-98 @@ -78,26 +92,26 @@ public class JdbcRepositoryIdGenerationIntegrationTests { PrimitiveIdEntity entity = new PrimitiveIdEntity(0); entity.setName("Entity Name"); - entity = primitiveIdRepository.save(entity); - assertThat(entity.getId()).isNotNull(); - assertThat(entity.getId()).isNotEqualTo(0L); + PrimitiveIdEntity saved = primitiveIdRepository.save(entity); - Optional reloadedEntity = primitiveIdRepository.findOne(entity.getId()); + assertThat(saved.getId()).isNotEqualTo(0L); - assertTrue(reloadedEntity.isPresent()); - assertEquals(entity.getId(), reloadedEntity.get().getId()); - assertEquals(entity.getName(), reloadedEntity.get().getName()); + assertThat(primitiveIdRepository.findOne(saved.getId())).hasValueSatisfying(it -> { + + assertThat(it.getId()).isEqualTo(saved.getId()); + assertThat(it.getName()).isEqualTo(saved.getName()); + }); } - private interface ReadOnlyIdEntityRepository extends CrudRepository {} - private interface PrimitiveIdEntityRepository extends CrudRepository {} - @Data + public interface ReadOnlyIdEntityRepository extends CrudRepository {} + + @Value static class ReadOnlyIdEntity { - @Id private final Long id; + @Id Long id; String name; } @@ -107,33 +121,4 @@ public class JdbcRepositoryIdGenerationIntegrationTests { @Id private final long id; String name; } - - @Configuration - @ComponentScan("org.springframework.data.jdbc.testing") - static class TestConfiguration { - - @Bean - Class testClass() { - return JdbcRepositoryIdGenerationIntegrationTests.class; - } - - @Bean - NamedParameterJdbcTemplate template(DataSource db) { - return new NamedParameterJdbcTemplate(db); - } - - @Bean - ReadOnlyIdEntityRepository readOnlyIdRepository(DataSource db) { - - return new JdbcRepositoryFactory(new NamedParameterJdbcTemplate(db), mock(ApplicationEventPublisher.class)) - .getRepository(ReadOnlyIdEntityRepository.class); - } - - @Bean - PrimitiveIdEntityRepository primitiveIdRepository(NamedParameterJdbcTemplate template) { - - return new JdbcRepositoryFactory(template, mock(ApplicationEventPublisher.class)) - .getRepository(PrimitiveIdEntityRepository.class); - } - } } diff --git a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 611310c6..d0e37d74 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -16,37 +16,27 @@ package org.springframework.data.jdbc.repository; import static java.util.Arrays.*; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.*; import lombok.Data; -import java.util.Optional; - -import javax.sql.DataSource; - import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; -import org.springframework.data.jdbc.repository.JdbcRepositoryIntegrationTests.TestConfiguration; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.repository.CrudRepository; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.rules.SpringClassRule; import org.springframework.test.context.junit4.rules.SpringMethodRule; import org.springframework.test.jdbc.JdbcTestUtils; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; /** @@ -54,61 +44,58 @@ import org.springframework.transaction.annotation.Transactional; * * @author Jens Schauder */ -@ContextConfiguration(classes = TestConfiguration.class) +@ContextConfiguration @Transactional public class JdbcRepositoryIntegrationTests { + @Configuration + @Import(TestConfiguration.class) + static class Config { + + @Autowired JdbcRepositoryFactory factory; + + @Bean + Class testClass() { + return JdbcRepositoryIntegrationTests.class; + } + + @Bean + DummyEntityRepository dummyEntityRepository() { + return factory.getRepository(DummyEntityRepository.class); + } + } + @ClassRule public static final SpringClassRule classRule = new SpringClassRule(); @Rule public SpringMethodRule methodRule = new SpringMethodRule(); @Autowired NamedParameterJdbcTemplate template; @Autowired DummyEntityRepository repository; - private DummyEntity entity = createDummyEntity(); - - private static DummyEntityRepository createRepository(EmbeddedDatabase db) { - - return new JdbcRepositoryFactory(new NamedParameterJdbcTemplate(db), mock(ApplicationEventPublisher.class)) - .getRepository(DummyEntityRepository.class); - } - - private static DummyEntity createDummyEntity() { - - DummyEntity entity = new DummyEntity(); - entity.setName("Entity Name"); - return entity; - } - @Test // DATAJDBC-95 public void savesAnEntity() { - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); - int count = JdbcTestUtils.countRowsInTableWhere( // - (JdbcTemplate) template.getJdbcOperations(), // - "dummyentity", // - "idProp = " + entity.getIdProp() // - ); - - assertEquals(1, count); + assertThat(JdbcTestUtils.countRowsInTableWhere((JdbcTemplate) template.getJdbcOperations(), "dummyentity", + "idProp = " + entity.getIdProp())).isEqualTo(1); } @Test // DATAJDBC-95 public void saveAndLoadAnEntity() { - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); - Optional reloadedEntity = repository.findOne(entity.getIdProp()); + assertThat(repository.findOne(entity.getIdProp())).hasValueSatisfying(it -> { - assertTrue(reloadedEntity.isPresent()); - - assertEquals(entity.getIdProp(), reloadedEntity.get().getIdProp()); - assertEquals(entity.getName(), reloadedEntity.get().getName()); + assertThat(it.getIdProp()).isEqualTo(entity.getIdProp()); + assertThat(it.getName()).isEqualTo(entity.getName()); + }); } @Test // DATAJDBC-97 public void savesManyEntities() { + DummyEntity entity = createDummyEntity(); DummyEntity other = createDummyEntity(); repository.save(asList(entity, other)); @@ -121,35 +108,34 @@ public class JdbcRepositoryIntegrationTests { @Test // DATAJDBC-97 public void existsReturnsTrueIffEntityExists() { - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); - assertTrue(repository.exists(entity.getIdProp())); - assertFalse(repository.exists(entity.getIdProp() + 1)); + assertThat(repository.exists(entity.getIdProp())).isTrue(); + assertThat(repository.exists(entity.getIdProp() + 1)).isFalse(); } @Test // DATAJDBC-97 public void findAllFindsAllEntities() { - DummyEntity other = createDummyEntity(); - - other = repository.save(other); - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); + DummyEntity other = repository.save(createDummyEntity()); Iterable all = repository.findAll(); - assertThat(all).extracting("idProp").containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp()); + assertThat(all)// + .extracting(DummyEntity::getIdProp)// + .containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp()); } @Test // DATAJDBC-97 public void findAllFindsAllSpecifiedEntities() { - entity = repository.save(entity); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); + DummyEntity entity = repository.save(createDummyEntity()); + DummyEntity other = repository.save(createDummyEntity()); - Iterable all = repository.findAll(asList(entity.getIdProp(), three.getIdProp())); - - assertThat(all).extracting("idProp").containsExactlyInAnyOrder(entity.getIdProp(), three.getIdProp()); + assertThat(repository.findAll(asList(entity.getIdProp(), other.getIdProp())))// + .extracting(DummyEntity::getIdProp)// + .containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp()); } @Test // DATAJDBC-97 @@ -157,7 +143,7 @@ public class JdbcRepositoryIntegrationTests { repository.save(createDummyEntity()); repository.save(createDummyEntity()); - repository.save(entity); + repository.save(createDummyEntity()); assertThat(repository.count()).isEqualTo(3L); } @@ -165,7 +151,7 @@ public class JdbcRepositoryIntegrationTests { @Test // DATAJDBC-97 public void deleteById() { - entity = repository.save(entity); + DummyEntity one = repository.save(createDummyEntity()); DummyEntity two = repository.save(createDummyEntity()); DummyEntity three = repository.save(createDummyEntity()); @@ -173,17 +159,17 @@ public class JdbcRepositoryIntegrationTests { assertThat(repository.findAll()) // .extracting(DummyEntity::getIdProp) // - .containsExactlyInAnyOrder(entity.getIdProp(), three.getIdProp()); + .containsExactlyInAnyOrder(one.getIdProp(), three.getIdProp()); } @Test // DATAJDBC-97 public void deleteByEntity() { - entity = repository.save(entity); + DummyEntity one = repository.save(createDummyEntity()); DummyEntity two = repository.save(createDummyEntity()); DummyEntity three = repository.save(createDummyEntity()); - repository.delete(entity); + repository.delete(one); assertThat(repository.findAll()) // .extracting(DummyEntity::getIdProp) // @@ -193,11 +179,11 @@ public class JdbcRepositoryIntegrationTests { @Test // DATAJDBC-97 public void deleteByList() { - repository.save(entity); + DummyEntity one = repository.save(createDummyEntity()); DummyEntity two = repository.save(createDummyEntity()); DummyEntity three = repository.save(createDummyEntity()); - repository.delete(asList(entity, three)); + repository.delete(asList(one, three)); assertThat(repository.findAll()) // .extracting(DummyEntity::getIdProp) // @@ -207,9 +193,11 @@ public class JdbcRepositoryIntegrationTests { @Test // DATAJDBC-97 public void deleteAll() { - repository.save(entity); repository.save(createDummyEntity()); repository.save(createDummyEntity()); + repository.save(createDummyEntity()); + + assertThat(repository.findAll()).isNotEmpty(); repository.deleteAll(); @@ -219,22 +207,20 @@ public class JdbcRepositoryIntegrationTests { @Test // DATAJDBC-98 public void update() { - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); entity.setName("something else"); + DummyEntity saved = repository.save(entity); - entity = repository.save(entity); - - Optional reloaded = repository.findOne(entity.getIdProp()); - - assertTrue(reloaded.isPresent()); - assertThat(reloaded.get().getName()).isEqualTo(entity.getName()); + assertThat(repository.findOne(entity.getIdProp())).hasValueSatisfying(it -> { + assertThat(it.getName()).isEqualTo(saved.getName()); + }); } @Test // DATAJDBC-98 public void updateMany() { - entity = repository.save(entity); + DummyEntity entity = repository.save(createDummyEntity()); DummyEntity other = repository.save(createDummyEntity()); entity.setName("something else"); @@ -247,7 +233,14 @@ public class JdbcRepositoryIntegrationTests { .containsExactlyInAnyOrder(entity.getName(), other.getName()); } - private interface DummyEntityRepository extends CrudRepository {} + private static DummyEntity createDummyEntity() { + + DummyEntity entity = new DummyEntity(); + entity.setName("Entity Name"); + return entity; + } + + interface DummyEntityRepository extends CrudRepository {} @Data static class DummyEntity { @@ -255,31 +248,4 @@ public class JdbcRepositoryIntegrationTests { String name; @Id private Long idProp; } - - @Configuration - @ComponentScan("org.springframework.data.jdbc.testing") - static class TestConfiguration { - - @Bean - Class testClass() { - return JdbcRepositoryIntegrationTests.class; - } - - @Bean - NamedParameterJdbcTemplate template(DataSource db) { - return new NamedParameterJdbcTemplate(db); - } - - @Bean - DummyEntityRepository readOnlyIdRepository(NamedParameterJdbcTemplate template) { - - return new JdbcRepositoryFactory(template, mock(ApplicationEventPublisher.class)) - .getRepository(DummyEntityRepository.class); - } - - @Bean - PlatformTransactionManager transactionManager(DataSource db) { - return new DataSourceTransactionManager(db); - } - } } diff --git a/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java b/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java index e5accf7b..86b2f56d 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java @@ -1,9 +1,9 @@ package org.springframework.data.jdbc.repository; import static java.util.Arrays.*; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import static org.springframework.util.Assert.*; import lombok.Data; @@ -22,7 +22,7 @@ import org.springframework.data.jdbc.mapping.event.AfterUpdate; import org.springframework.data.jdbc.mapping.event.BeforeDelete; import org.springframework.data.jdbc.mapping.event.BeforeInsert; import org.springframework.data.jdbc.mapping.event.BeforeUpdate; -import org.springframework.data.jdbc.mapping.event.Identifier.Specified; +import org.springframework.data.jdbc.mapping.event.Identifier; import org.springframework.data.jdbc.mapping.event.JdbcEvent; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; import org.springframework.data.repository.CrudRepository; @@ -35,9 +35,9 @@ import org.springframework.jdbc.support.KeyHolder; */ public class SimpleJdbcRepositoryEventsUnitTests { - private FakePublisher publisher = new FakePublisher(); + FakePublisher publisher = new FakePublisher(); - private DummyEntityRepository repository; + DummyEntityRepository repository; @Before public void before() { @@ -47,7 +47,58 @@ public class SimpleJdbcRepositoryEventsUnitTests { repository = factory.getRepository(DummyEntityRepository.class); } - private NamedParameterJdbcOperations createIdGeneratingOperations() { + @Test // DATAJDBC-99 + public void publishesEventsOnSave() { + + DummyEntity entity = new DummyEntity(23L); + + repository.save(entity); + + assertThat(publisher.events.get(0)).isInstanceOf(BeforeUpdate.class); + assertThat(publisher.events.get(1)).isInstanceOf(AfterUpdate.class); + } + + @Test // DATAJDBC-99 + public void publishesEventsOnSaveMany() { + + DummyEntity entity1 = new DummyEntity(null); + DummyEntity entity2 = new DummyEntity(23L); + + repository.save(asList(entity1, entity2)); + + assertThat(publisher.events.get(0)).isInstanceOf(BeforeInsert.class); + assertThat(publisher.events.get(1)).isInstanceOf(AfterInsert.class); + assertThat(publisher.events.get(2)).isInstanceOf(BeforeUpdate.class); + assertThat(publisher.events.get(3)).isInstanceOf(AfterUpdate.class); + } + + @Test // DATAJDBC-99 + public void publishesEventsOnDelete() { + + DummyEntity entity = new DummyEntity(23L); + + repository.delete(entity); + + assertThat(publisher.events.get(0)).isInstanceOf(BeforeDelete.class); + assertThat(publisher.events.get(1)).isInstanceOf(AfterDelete.class); + + assertThat(publisher.events.get(0).getOptionalEntity()).hasValue(entity); + assertThat(publisher.events.get(1).getOptionalEntity()).hasValue(entity); + + assertThat(publisher.events.get(0).getId()).isEqualTo(Identifier.of(23L)); + assertThat(publisher.events.get(1).getId()).isEqualTo(Identifier.of(23L)); + } + + @Test // DATAJDBC-99 + public void publishesEventsOnDeleteById() { + + repository.delete(23L); + + assertThat(publisher.events.get(0)).isInstanceOf(BeforeDelete.class); + assertThat(publisher.events.get(1)).isInstanceOf(AfterDelete.class); + } + + private static NamedParameterJdbcOperations createIdGeneratingOperations() { Answer setIdInKeyHolder = invocation -> { @@ -65,62 +116,11 @@ public class SimpleJdbcRepositoryEventsUnitTests { return operations; } - @Test // DATAJDBC-99 - public void publishesEventsOnSave() { - - DummyEntity entity = new DummyEntity(23L); - - repository.save(entity); - - isInstanceOf(BeforeUpdate.class, publisher.events.get(0)); - isInstanceOf(AfterUpdate.class, publisher.events.get(1)); - } - - @Test // DATAJDBC-99 - public void publishesEventsOnSaveMany() { - - DummyEntity entity1 = new DummyEntity(null); - DummyEntity entity2 = new DummyEntity(23L); - - repository.save(asList(entity1, entity2)); - - isInstanceOf(BeforeInsert.class, publisher.events.get(0)); - isInstanceOf(AfterInsert.class, publisher.events.get(1)); - isInstanceOf(BeforeUpdate.class, publisher.events.get(2)); - isInstanceOf(AfterUpdate.class, publisher.events.get(3)); - } - - @Test // DATAJDBC-99 - public void publishesEventsOnDelete() { - - DummyEntity entity = new DummyEntity(23L); - - repository.delete(entity); - - isInstanceOf(BeforeDelete.class, publisher.events.get(0)); - isInstanceOf(AfterDelete.class, publisher.events.get(1)); - - assertEquals(entity, publisher.events.get(0).getOptionalEntity().get()); - assertEquals(entity, publisher.events.get(1).getOptionalEntity().get()); - - assertEquals(new Specified(23L), publisher.events.get(0).getId()); - assertEquals(new Specified(23L), publisher.events.get(1).getId()); - } - - @Test // DATAJDBC-99 - public void publishesEventsOnDeleteById() { - - repository.delete(23L); - - isInstanceOf(BeforeDelete.class, publisher.events.get(0)); - isInstanceOf(AfterDelete.class, publisher.events.get(1)); - } - - private interface DummyEntityRepository extends CrudRepository {} + interface DummyEntityRepository extends CrudRepository {} @Data - private static class DummyEntity { - @Id private final Long id; + static class DummyEntity { + private final @Id Long id; } static class FakePublisher implements ApplicationEventPublisher { diff --git a/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java b/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java new file mode 100644 index 00000000..01db760c --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java @@ -0,0 +1,79 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.testing; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +/** + * Basic configuration expecting subclasses to provide a {@link DataSource} via {@link #createDataSource()} to be + * exposed to the {@link ApplicationContext}. + * + * @author Jens Schauder + * @author Oliver Gierke + */ +@Configuration +abstract class DataSourceConfiguration { + + @Autowired Class testClass; + @Autowired Environment environment; + + @Bean + DataSource dataSource() { + return createDataSource(); + } + + @Bean + DataSourceInitializer initializer() { + + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource()); + + String[] activeProfiles = environment.getActiveProfiles(); + String profile = activeProfiles.length == 0 ? "" : activeProfiles[0]; + + ClassPathResource script = new ClassPathResource(TestUtils.createScriptName(testClass, profile)); + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(script); + customizePopulator(populator); + initializer.setDatabasePopulator(populator); + + return initializer; + } + + /** + * Return the {@link DataSource} to be exposed as a Spring bean. + * + * @return + */ + protected abstract DataSource createDataSource(); + + /** + * Callback to customize the {@link ResourceDatabasePopulator} before it will be applied to the {@link DataSource}. It + * will be pre-populated with a SQL script derived from the name of the current test class and the activated Spring + * profile. + * + * @param populator will never be {@literal null}. + */ + protected void customizePopulator(ResourceDatabasePopulator populator) {} +} diff --git a/src/test/java/org/springframework/data/jdbc/testing/DataSourceFactoryBean.java b/src/test/java/org/springframework/data/jdbc/testing/DataSourceFactoryBean.java deleted file mode 100644 index df4cbe5b..00000000 --- a/src/test/java/org/springframework/data/jdbc/testing/DataSourceFactoryBean.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.jdbc.testing; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.FactoryBean; - -/** - * @author Jens Schauder - */ -abstract class DataSourceFactoryBean implements FactoryBean { - - private final Class testClass; - - DataSourceFactoryBean(Class testClass) { - this.testClass = testClass; - } - - private DataSource createDataSource() { - return create(createScriptName(testClass, scriptSuffix())); - } - - abstract String scriptSuffix(); - - abstract DataSource create(String scriptName); - - private String createScriptName(Class testClass, String databaseType) { - - return String.format( // - "%s/%s-%s.sql", // - testClass.getPackage().getName(), // - testClass.getSimpleName(), // - databaseType.toLowerCase()); - } - - @Override - public DataSource getObject() throws Exception { - return createDataSource(); - } - - @Override - public Class getObjectType() { - return DataSource.class; - } -} diff --git a/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceFactoryBean.java b/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java similarity index 73% rename from src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceFactoryBean.java rename to src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java index dbe832a0..0b92c63c 100644 --- a/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceFactoryBean.java +++ b/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java @@ -17,36 +17,34 @@ package org.springframework.data.jdbc.testing; import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.stereotype.Component; /** + * {@link DataSource} setup for HSQL. + * * @author Jens Schauder + * @author Oliver Gierke */ -@Component +@Configuration @Profile({ "hsql", "default" }) -class HsqlDataSourceFactoryBean extends DataSourceFactoryBean { +class HsqlDataSourceConfiguration { - HsqlDataSourceFactoryBean(Class testClass) { - super(testClass); - } + @Autowired Class context; - @Override - String scriptSuffix() { - return "hsql"; - } - - @Override - DataSource create(String scriptName) { + @Bean + DataSource dataSource() { return new EmbeddedDatabaseBuilder() // .generateUniqueName(true) // .setType(EmbeddedDatabaseType.HSQL) // .setScriptEncoding("UTF-8") // .ignoreFailedDrops(true) // - .addScript(scriptName) // + .addScript(TestUtils.createScriptName(context, "hsql")) // .build(); } } diff --git a/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceConfiguration.java b/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceConfiguration.java new file mode 100644 index 00000000..2bd81a50 --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceConfiguration.java @@ -0,0 +1,66 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.testing; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.DatabasePopulator; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; + +/** + * {@link DataSource} setup for MySQL. + * + * @author Jens Schauder + * @author Oliver Gierke + */ +@Configuration +@Profile("mysql") +class MySqlDataSourceConfiguration extends DataSourceConfiguration { + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.testing.DataSourceConfiguration#createDataSource() + */ + protected DataSource createDataSource() { + + MysqlDataSource dataSource = new MysqlDataSource(); + dataSource.setUrl("jdbc:mysql:///test?user=root"); + + return dataSource; + } + + @PostConstruct + public void initDatabase() { + + MysqlDataSource dataSource = new MysqlDataSource(); + dataSource.setUrl("jdbc:mysql:///?user=root"); + + ClassPathResource createScript = new ClassPathResource("create-mysql.sql"); + DatabasePopulator databasePopulator = new ResourceDatabasePopulator(createScript); + + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDatabasePopulator(databasePopulator); + initializer.setDataSource(dataSource); + initializer.afterPropertiesSet(); + } +} diff --git a/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceFactoryBean.java b/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceFactoryBean.java deleted file mode 100644 index 7ec34489..00000000 --- a/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceFactoryBean.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.jdbc.testing; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.jdbc.datasource.init.ScriptUtils; -import org.springframework.stereotype.Component; - -import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; - -/** - * @author Jens Schauder - */ -@Component -@Profile("mysql") -class MySqlDataSourceFactoryBean extends DataSourceFactoryBean { - - public static final String ROOT_URL = "jdbc:mysql:///?user=root"; - public static final String COULDN_T_CREATE_DATABASE = // - "Couldn't create database. Maybe you don't have a MySql database running, reachable at %s"; - private static final DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); - private static final String TEST_URL = "jdbc:mysql:///test?user=root"; - - MySqlDataSourceFactoryBean(Class testClass) { - super(testClass); - } - - @Override - String scriptSuffix() { - return "mysql"; - } - - @Override - DataSource create(String scriptName) { - - createDatabase(); - return setupDatabase(scriptName); - } - - private MysqlDataSource setupDatabase(String scriptName) { - - MysqlDataSource ds = new MysqlDataSource(); - ds.setUrl(TEST_URL); - - try (Connection connection = ds.getConnection()) { - ScriptUtils.executeSqlScript(connection, resourceLoader.getResource(scriptName)); - } catch (SQLException e) { - throw new RuntimeException("Couldn't setup database", e); - } - - return ds; - } - - private void createDatabase() { - - MysqlDataSource initialDs = new MysqlDataSource(); - initialDs.setUrl(ROOT_URL); - - try (Connection connection = initialDs.getConnection()) { - ScriptUtils.executeSqlScript(connection, resourceLoader.getResource("create-mysql.sql")); - } catch (SQLException e) { - throw new RuntimeException(String.format(COULDN_T_CREATE_DATABASE, ROOT_URL), e); - } - } -} diff --git a/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceConfiguration.java b/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceConfiguration.java new file mode 100644 index 00000000..6a7f1925 --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.testing; + +import javax.sql.DataSource; + +import org.postgresql.ds.PGSimpleDataSource; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +/** + * {@link DataSource} setup for PostgreSQL + * + * @author Jens Schauder + * @author Oliver Gierke + */ +@Configuration +@Profile("postgres") +public class PostgresDataSourceConfiguration extends DataSourceConfiguration { + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.testing.DataSourceConfiguration#createDataSource() + */ + protected DataSource createDataSource() { + + PGSimpleDataSource ds = new PGSimpleDataSource(); + ds.setUrl("jdbc:postgresql:///postgres"); + + return ds; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jdbc.testing.DataSourceFactoryBean#customizePopulator(org.springframework.jdbc.datasource.init.ResourceDatabasePopulator) + */ + @Override + protected void customizePopulator(ResourceDatabasePopulator populator) { + populator.setIgnoreFailedDrops(true); + } +} diff --git a/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceFactoryBean.java b/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceFactoryBean.java deleted file mode 100644 index 25b3fa7f..00000000 --- a/src/test/java/org/springframework/data/jdbc/testing/PostgresDataSourceFactoryBean.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.jdbc.testing; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.postgresql.ds.PGSimpleDataSource; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.support.EncodedResource; -import org.springframework.jdbc.datasource.init.ScriptUtils; -import org.springframework.stereotype.Component; - -/** - * @author Jens Schauder - */ -@Component -@Profile("postgres") -public class PostgresDataSourceFactoryBean extends DataSourceFactoryBean { - - public static final String URL = "jdbc:postgresql:///postgres"; - private static final DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); - - PostgresDataSourceFactoryBean(Class testClass) { - super(testClass); - } - - @Override - protected String scriptSuffix() { - return "postgres"; - } - - @Override - DataSource create(String scriptName) { - return setupDatabase(scriptName); - } - - private DataSource setupDatabase(String scriptName) { - - PGSimpleDataSource ds = new PGSimpleDataSource(); - ds.setUrl(URL); - - try (Connection connection = ds.getConnection()) { - - ScriptUtils.executeSqlScript(connection, new EncodedResource(resourceLoader.getResource(scriptName)), false, true, - "--", ";", "/*", "*/"); - } catch (SQLException e) { - throw new RuntimeException("Couldn't setup database", e); - } - - return ds; - } -} diff --git a/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java b/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java new file mode 100644 index 00000000..0c93cc3f --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.testing; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +/** + * Infrastructure configuration for integration tests. + * + * @author Oliver Gierke + */ +@Configuration +@ComponentScan // To pick up configuration classes (per activated profile) +public class TestConfiguration { + + @Autowired DataSource dataSource; + @Autowired ApplicationEventPublisher publisher; + + @Bean + JdbcRepositoryFactory jdbcRepositoryFactory() { + return new JdbcRepositoryFactory(namedParameterJdbcTemplate(), publisher); + } + + @Bean + NamedParameterJdbcTemplate namedParameterJdbcTemplate() { + return new NamedParameterJdbcTemplate(dataSource); + } + + @Bean + PlatformTransactionManager transactionManager() { + return new DataSourceTransactionManager(dataSource); + } +} diff --git a/src/test/java/org/springframework/data/jdbc/testing/TestUtils.java b/src/test/java/org/springframework/data/jdbc/testing/TestUtils.java new file mode 100644 index 00000000..e9e1a5dc --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/testing/TestUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.testing; + +import org.springframework.util.Assert; + +/** + * Utility methods for testing. + * + * @author Oliver Gierke + */ +public interface TestUtils { + + /** + * Returns the name of the SQL script to be loaded for the given test class and database type. + * + * @param testClass must not be {@literal null}. + * @param databaseType must not be {@literal null} or empty. + * @return + */ + public static String createScriptName(Class testClass, String databaseType) { + + Assert.notNull(testClass, "Test class must not be null!"); + Assert.hasText(databaseType, "Database type must not be null or empty!"); + + return String.format("%s/%s-%s.sql", testClass.getPackage().getName(), testClass.getSimpleName(), + databaseType.toLowerCase()); + } +} diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml new file mode 100644 index 00000000..ad5cbef5 --- /dev/null +++ b/src/test/resources/logback.xml @@ -0,0 +1,16 @@ + + + + + + %d %5p %40.40c:%4L - %m%n + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-hsql.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-hsql.sql index 60408124..1618e256 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-hsql.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-hsql.sql @@ -1,4 +1,4 @@ -- noinspection SqlNoDataSourceInspectionForFile CREATE TABLE ReadOnlyIdEntity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, NAME VARCHAR(100)) -CREATE TABLE PrimitiveIdEntity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, NAME VARCHAR(100)) \ No newline at end of file +CREATE TABLE PrimitiveIdEntity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, NAME VARCHAR(100)) diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-mysql.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-mysql.sql index 2ef12bbf..b02242b2 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-mysql.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-mysql.sql @@ -1,2 +1,2 @@ CREATE TABLE ReadOnlyIdEntity (ID BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); -CREATE TABLE PrimitiveIdEntity (ID BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); \ No newline at end of file +CREATE TABLE PrimitiveIdEntity (ID BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-postgres.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-postgres.sql index 3c8e7908..267f0b7a 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-postgres.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-postgres.sql @@ -2,4 +2,4 @@ DROP TABLE ReadOnlyIdEntity; DROP TABLE PrimitiveIdEntity; CREATE TABLE ReadOnlyIdEntity (ID SERIAL PRIMARY KEY, NAME VARCHAR(100)); -CREATE TABLE PrimitiveIdEntity (ID SERIAL PRIMARY KEY, NAME VARCHAR(100)); \ No newline at end of file +CREATE TABLE PrimitiveIdEntity (ID SERIAL PRIMARY KEY, NAME VARCHAR(100)); diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql index db94760d..d6458976 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql @@ -1 +1 @@ -CREATE TABLE dummyentity ( idProp BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100)) \ No newline at end of file +CREATE TABLE dummyentity ( idProp BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100)) diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql index 3b204a37..89763ecd 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql @@ -1 +1 @@ -CREATE TABLE dummyentity (idProp BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); \ No newline at end of file +CREATE TABLE dummyentity (idProp BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql index 64e1d154..25e9c426 100644 --- a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql @@ -1,2 +1,2 @@ DROP TABLE dummyentity; -CREATE TABLE dummyentity (idProp SERIAL PRIMARY KEY, NAME VARCHAR(100)); \ No newline at end of file +CREATE TABLE dummyentity (idProp SERIAL PRIMARY KEY, NAME VARCHAR(100));