Initial import
This commit is contained in:
parent
881580f2fe
commit
6ac9c01d3d
|
@ -19,10 +19,13 @@ import javax.persistence.criteria.CriteriaDelete;
|
|||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.CriteriaUpdate;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.olingo.odata2.api.processor.ODataContext;
|
||||
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
|
||||
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
|
||||
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
|
||||
import org.baeldung.examples.olingo2.JerseyConfig.EntityManagerFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||
|
@ -44,7 +47,6 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory {
|
|||
setDetailErrors(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will be called by Olingo on every request to
|
||||
* initialize the ODataJPAContext that will be used.
|
||||
|
@ -54,18 +56,18 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory {
|
|||
|
||||
log.info("[I32] >>> initializeODataJPAContext()");
|
||||
ODataJPAContext ctx = getODataJPAContext();
|
||||
ODataContext octx = ctx.getODataContext();
|
||||
HttpServletRequest request = (HttpServletRequest)octx.getParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
|
||||
EntityManager em = (EntityManager)request.getAttribute(EntityManagerFilter.EM_REQUEST_ATTRIBUTE);
|
||||
|
||||
// Here we're passing the EM that was created by the EntityManagerFilter (see JerseyConfig)
|
||||
ctx.setEntityManager(new EntityManagerWrapper(EntityManagerHolder.getCurrentEntityManager()));
|
||||
ctx.setEntityManager(new EntityManagerWrapper(em));
|
||||
ctx.setPersistenceUnitName("default");
|
||||
|
||||
// We're managing the EM's lifecycle, so we must inform Olingo that it should not
|
||||
// try to manage transactions and/or persistence sessions
|
||||
ctx.setContainerManaged(true);
|
||||
|
||||
|
||||
return ctx;
|
||||
|
||||
}
|
||||
|
||||
static class EntityManagerWrapper implements EntityManager {
|
||||
|
@ -73,18 +75,21 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory {
|
|||
private EntityManager delegate;
|
||||
|
||||
public void persist(Object entity) {
|
||||
log.info("[I68] persist: entity.class=" + entity.getClass().getSimpleName());
|
||||
log.info("[I68] persist: entity.class=" + entity.getClass()
|
||||
.getSimpleName());
|
||||
delegate.persist(entity);
|
||||
//delegate.flush();
|
||||
// delegate.flush();
|
||||
}
|
||||
|
||||
public <T> T merge(T entity) {
|
||||
log.info("[I74] merge: entity.class=" + entity.getClass().getSimpleName());
|
||||
log.info("[I74] merge: entity.class=" + entity.getClass()
|
||||
.getSimpleName());
|
||||
return delegate.merge(entity);
|
||||
}
|
||||
|
||||
public void remove(Object entity) {
|
||||
log.info("[I78] remove: entity.class=" + entity.getClass().getSimpleName());
|
||||
log.info("[I78] remove: entity.class=" + entity.getClass()
|
||||
.getSimpleName());
|
||||
delegate.remove(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
package org.baeldung.examples.olingo2;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
public class EntityManagerHolder {
|
||||
|
||||
private static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<>();
|
||||
|
||||
|
||||
public static void setCurrentEntityManager(EntityManager em) {
|
||||
currentEntityManager.set(em);
|
||||
}
|
||||
|
||||
public static EntityManager getCurrentEntityManager() {
|
||||
return currentEntityManager.get();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.baeldung.examples.olingo2;
|
||||
package org.baeldung.examples.olingo2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -6,12 +6,14 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.container.ContainerResponseContext;
|
||||
import javax.ws.rs.container.ContainerResponseFilter;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
import org.apache.olingo.odata2.api.ODataServiceFactory;
|
||||
|
@ -59,9 +61,13 @@ public class JerseyConfig extends ResourceConfig {
|
|||
public static class EntityManagerFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EntityManagerFilter.class);
|
||||
public static final String EM_REQUEST_ATTRIBUTE = EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";
|
||||
|
||||
private final EntityManagerFactory emf;
|
||||
|
||||
@Context
|
||||
private HttpServletRequest httpRequest;
|
||||
|
||||
public EntityManagerFilter(EntityManagerFactory emf) {
|
||||
this.emf = emf;
|
||||
}
|
||||
|
@ -70,11 +76,12 @@ public class JerseyConfig extends ResourceConfig {
|
|||
public void filter(ContainerRequestContext ctx) throws IOException {
|
||||
log.info("[I60] >>> filter");
|
||||
EntityManager em = this.emf.createEntityManager();
|
||||
EntityManagerHolder.setCurrentEntityManager(em);
|
||||
httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, em);
|
||||
|
||||
// Start a new transaction unless we have a simple GET
|
||||
if ( !"GET".equalsIgnoreCase(ctx.getMethod())) {
|
||||
em.getTransaction().begin();
|
||||
if (!"GET".equalsIgnoreCase(ctx.getMethod())) {
|
||||
em.getTransaction()
|
||||
.begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,12 +89,12 @@ public class JerseyConfig extends ResourceConfig {
|
|||
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
|
||||
|
||||
log.info("[I68] <<< filter");
|
||||
EntityManager em = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE);
|
||||
|
||||
EntityManager em = EntityManagerHolder.getCurrentEntityManager();
|
||||
if ( em != null && !"GET".equalsIgnoreCase(requestContext.getMethod())) {
|
||||
if (!"GET".equalsIgnoreCase(requestContext.getMethod())) {
|
||||
EntityTransaction t = em.getTransaction();
|
||||
if ( t.isActive()) {
|
||||
if ( !t.getRollbackOnly()) {
|
||||
if (t.isActive()) {
|
||||
if (!t.getRollbackOnly()) {
|
||||
t.commit();
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +106,6 @@ public class JerseyConfig extends ResourceConfig {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Path("/")
|
||||
public static class CarsRootLocator extends ODataRootLocator {
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
server:
|
||||
port: 8180
|
||||
|
||||
spring:
|
||||
jersey:
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
HELP.md
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>org.baeldung.examples.olingo4</groupId>
|
||||
<artifactId>olingo4-sample</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>olingo4-sample</name>
|
||||
<description>Sample Olingo 4 Project</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<odata.version>4.5.0</odata.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-server-api</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-server-core</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-commons-api</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-commons-core</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,20 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Default implementation for ODataFactory
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class DefaultODataFactory implements ODataFactory {
|
||||
|
||||
@Override
|
||||
public OData newInstance() {
|
||||
return OData.newInstance();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.OData;
|
||||
|
||||
public interface ODataFactory {
|
||||
|
||||
public OData newInstance();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
|
||||
public interface ODataHttpHandlerFactory {
|
||||
|
||||
ODataHttpHandler newInstance();
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@Builder
|
||||
public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory {
|
||||
|
||||
|
||||
private final ODataFactory odataFactory;
|
||||
private final CsdlEdmProvider edmProvider;
|
||||
private final List<Processor> processors;
|
||||
|
||||
public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory,CsdlEdmProvider edmProvider, List<Processor> processors) {
|
||||
this.odataFactory = odataFactory;
|
||||
this.edmProvider = edmProvider;
|
||||
this.processors = processors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataHttpHandler newInstance() {
|
||||
|
||||
OData odata = odataFactory.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList());
|
||||
ODataHttpHandler handler = odata.createHandler(metadata);
|
||||
|
||||
// Register all available processors
|
||||
processors.forEach(p -> handler.register(p));
|
||||
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.baeldung.examples.olingo4.ODataHttpHandlerFactoryImpl.ODataHttpHandlerFactoryImplBuilder;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ODataServiceConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean<HttpServlet> odataServletRegistration(ODataHttpHandlerFactory factory, EntityManagerFactory emf) {
|
||||
|
||||
ServletRegistrationBean bean = new ServletRegistrationBean(
|
||||
odataServlet(factory,emf),
|
||||
"/odata/*");
|
||||
bean.setLoadOnStartup(1);
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public HttpServlet odataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf ) {
|
||||
|
||||
return new ODataServlet(factory,emf);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List<Processor> processors) {
|
||||
return new ODataHttpHandlerFactoryImplBuilder()
|
||||
.edmProvider(edmProvider)
|
||||
.odataFactory(odataFactory)
|
||||
.processors(processors)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
public class ODataServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final ODataHttpHandlerFactory odataHttpHandlerFactory;
|
||||
|
||||
|
||||
public ODataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf) {
|
||||
this.odataHttpHandlerFactory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
|
||||
ODataHttpHandler handler = odataHttpHandlerFactory.newInstance();
|
||||
handler.process(req, resp);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Olingo4SampleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Olingo4SampleApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package org.baeldung.examples.olingo4.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name="car_maker")
|
||||
public class CarMaker {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
@Column(name="name")
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy="maker",
|
||||
orphanRemoval = true,
|
||||
cascade=CascadeType.ALL)
|
||||
private List<CarModel> models;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.baeldung.examples.olingo4.domain;
|
||||
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name="car_model")
|
||||
public class CarModel {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
private String name;
|
||||
|
||||
@NotNull
|
||||
private Integer year;
|
||||
|
||||
@NotNull
|
||||
private String sku;
|
||||
|
||||
@ManyToOne(optional=false, fetch= FetchType.LAZY)
|
||||
@JoinColumn(name="maker_fk")
|
||||
private CarMaker maker;
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.baeldung.examples.olingo4.edm;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.sql.Time;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class EdmTypeMapper {
|
||||
|
||||
public EdmPrimitiveTypeKind java2edm(Class<?> clazz) {
|
||||
EdmPrimitiveTypeKind result = java2edm.get(clazz);
|
||||
if ( result == null ) {
|
||||
throw new IllegalArgumentException("[E19] Unsupported class mapping: class=" + clazz);
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Static map used generate attribute metadada based on Java types
|
||||
static Map<Class<?>,EdmPrimitiveTypeKind> java2edm = Collections
|
||||
.unmodifiableMap(Stream.of(
|
||||
new SimpleEntry<>(Boolean.class,EdmPrimitiveTypeKind.Boolean),
|
||||
new SimpleEntry<>(Byte.class,EdmPrimitiveTypeKind.SByte),
|
||||
new SimpleEntry<>(Date.class,EdmPrimitiveTypeKind.Date),
|
||||
new SimpleEntry<>(Time.class,EdmPrimitiveTypeKind.TimeOfDay),
|
||||
new SimpleEntry<>(Number.class,EdmPrimitiveTypeKind.Decimal),
|
||||
new SimpleEntry<>(Float.class,EdmPrimitiveTypeKind.Single),
|
||||
new SimpleEntry<>(Double.class,EdmPrimitiveTypeKind.Double),
|
||||
new SimpleEntry<>(UUID.class,EdmPrimitiveTypeKind.Guid),
|
||||
new SimpleEntry<>(Short.class,EdmPrimitiveTypeKind.Int16),
|
||||
new SimpleEntry<>(Integer.class,EdmPrimitiveTypeKind.Int32),
|
||||
new SimpleEntry<>(Long.class,EdmPrimitiveTypeKind.Int64),
|
||||
new SimpleEntry<>(String.class,EdmPrimitiveTypeKind.String)
|
||||
|
||||
).collect(Collectors.toMap((e)-> e.getKey(),(e)-> e.getValue())));
|
||||
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
package org.baeldung.examples.olingo4.edm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.Attribute.PersistentAttributeType;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
|
||||
import org.apache.olingo.commons.api.ex.ODataException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JpaEdmProvider extends CsdlAbstractEdmProvider {
|
||||
|
||||
EntityManagerFactory emf;
|
||||
|
||||
//
|
||||
private EdmTypeMapper typeMapper;
|
||||
|
||||
// Service Namespace
|
||||
public static final String NAMESPACE = "OData.Demo";
|
||||
|
||||
// EDM Container
|
||||
public static final String CONTAINER_NAME = "Cars";
|
||||
public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
|
||||
|
||||
public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) {
|
||||
this.emf = emf;
|
||||
this.typeMapper = mapper;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntitySet(org.apache.olingo.commons.api.edm.FullQualifiedName, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
|
||||
|
||||
if (entityContainer.equals(CONTAINER)) {
|
||||
|
||||
EntityType<?> e = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.filter((ent) -> (ent.getName() + "s")
|
||||
.equals(entitySetName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (e != null) {
|
||||
CsdlEntitySet entitySet = new CsdlEntitySet();
|
||||
entitySet.setName(entitySetName);
|
||||
entitySet.setType(new FullQualifiedName(NAMESPACE, e.getName()));
|
||||
return entitySet;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainerInfo(org.apache.olingo.commons.api.edm.FullQualifiedName)
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
|
||||
|
||||
// This method is invoked when displaying the Service Document at e.g. http://localhost:8080/DemoService/DemoService.svc
|
||||
if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
|
||||
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
|
||||
entityContainerInfo.setContainerName(CONTAINER);
|
||||
return entityContainerInfo;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getSchemas()
|
||||
*/
|
||||
@Override
|
||||
public List<CsdlSchema> getSchemas() throws ODataException {
|
||||
// create Schema
|
||||
CsdlSchema schema = new CsdlSchema();
|
||||
schema.setNamespace(NAMESPACE);
|
||||
|
||||
// add EntityTypes
|
||||
List<CsdlEntityType> entityTypes = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.map((e) -> {
|
||||
try {
|
||||
return getEntityType(new FullQualifiedName(NAMESPACE, e.getName()));
|
||||
} catch (ODataException oe) {
|
||||
throw new RuntimeException(oe);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
schema.setEntityTypes(entityTypes);
|
||||
|
||||
// add EntityContainer
|
||||
schema.setEntityContainer(getEntityContainer());
|
||||
|
||||
// finally
|
||||
List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
|
||||
schemas.add(schema);
|
||||
|
||||
return schemas;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainer()
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntityContainer getEntityContainer() throws ODataException {
|
||||
|
||||
|
||||
// add EntityTypes
|
||||
List<CsdlEntitySet> entitySets = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.map((e) -> {
|
||||
try {
|
||||
// Here we use a simple mapping strategy to map entity types to entity set names:
|
||||
//
|
||||
return getEntitySet(CONTAINER, e.getName() + "s");
|
||||
} catch (ODataException oe) {
|
||||
throw new RuntimeException(oe);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// create EntityContainer
|
||||
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
|
||||
entityContainer.setName(CONTAINER_NAME);
|
||||
entityContainer.setEntitySets(entitySets);
|
||||
|
||||
return entityContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
|
||||
|
||||
Metamodel mm = emf.getMetamodel();
|
||||
|
||||
CsdlEntityType result = null;
|
||||
|
||||
result = mm.getEntities()
|
||||
.stream()
|
||||
.filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName())))
|
||||
.map(et -> buildODataType(et))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a JPA type to its OData counterpart.
|
||||
* @param et
|
||||
* @return
|
||||
*/
|
||||
protected CsdlEntityType buildODataType(EntityType<?> et) {
|
||||
|
||||
CsdlEntityType result = new CsdlEntityType();
|
||||
result.setName(et.getName());
|
||||
|
||||
// Process simple properties
|
||||
List<CsdlProperty> properties = et.getDeclaredSingularAttributes()
|
||||
.stream()
|
||||
.filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC)
|
||||
.map(attr -> buildBasicAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
result.setProperties(properties);
|
||||
|
||||
// Process Ids
|
||||
List<CsdlPropertyRef> ids = et.getDeclaredSingularAttributes()
|
||||
.stream()
|
||||
.filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId())
|
||||
.map(attr -> buildRefAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
result.setKey(ids);
|
||||
|
||||
// Process navs
|
||||
List<CsdlNavigationProperty> navs = et.getDeclaredPluralAttributes()
|
||||
.stream()
|
||||
.map(attr -> buildNavAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
result.setNavigationProperties(navs);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private CsdlProperty buildBasicAttribute(EntityType<?> et, SingularAttribute<?, ?> attr) {
|
||||
|
||||
CsdlProperty p = new CsdlProperty().setName(attr.getName())
|
||||
.setType(typeMapper.java2edm(attr.getJavaType())
|
||||
.getFullQualifiedName())
|
||||
.setNullable(et.getDeclaredSingularAttribute(attr.getName())
|
||||
.isOptional());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private CsdlPropertyRef buildRefAttribute(EntityType<?> et, SingularAttribute<?, ?> attr) {
|
||||
|
||||
CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private CsdlNavigationProperty buildNavAttribute(EntityType<?> et, PluralAttribute<?, ?, ?> attr) {
|
||||
|
||||
CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName())
|
||||
.setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName()))
|
||||
.setNullable(false); // for now
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
package org.baeldung.examples.olingo4.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataLibraryException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.SerializerResult;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.baeldung.examples.olingo4.repository.RepositoryRegistry;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JpaEntityCollectionProcessor implements CountEntityCollectionProcessor {
|
||||
|
||||
private OData odata;
|
||||
private ServiceMetadata serviceMetadata;
|
||||
private EntityManagerFactory emf;
|
||||
private RepositoryRegistry repositoryRegistry;
|
||||
|
||||
public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry) {
|
||||
this.emf = emf;
|
||||
this.repositoryRegistry = repositoryRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(OData odata, ServiceMetadata serviceMetadata) {
|
||||
this.odata = odata;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
// 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI)
|
||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
|
||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||
|
||||
// 2nd: fetch the data from backend for this requested EntitySetName
|
||||
// it has to be delivered as EntitySet object
|
||||
EntityCollection entitySet = getData(edmEntitySet, uriInfo);
|
||||
|
||||
// 3rd: create a serializer based on the requested format (json)
|
||||
ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||
|
||||
// 4th: Now serialize the content: transform from the EntitySet object to InputStream
|
||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||
ContextURL contextUrl = ContextURL.with()
|
||||
.entitySet(edmEntitySet)
|
||||
.build();
|
||||
|
||||
final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName();
|
||||
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
|
||||
.id(id)
|
||||
.contextURL(contextUrl)
|
||||
.build();
|
||||
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts);
|
||||
InputStream serializedContent = serializerResult.getContent();
|
||||
|
||||
// Finally: configure the response object: set the body, headers and status code
|
||||
response.setContent(serializedContent);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
// 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI)
|
||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
|
||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||
|
||||
// 2nd: fetch the data from backend for this requested EntitySetName
|
||||
Long count = getCount(edmEntitySet, uriInfo);
|
||||
|
||||
// Finally: configure the response object: set the body, headers and status code
|
||||
response.setContent(new ByteArrayInputStream(count.toString()
|
||||
.getBytes()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
|
||||
}
|
||||
|
||||
private EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
|
||||
|
||||
EdmEntityType type = edmEntitySet.getEntityType();
|
||||
JpaRepository<?, ?> repo = repositoryRegistry.getRepositoryForEntity(type);
|
||||
EntityCollection result = new EntityCollection();
|
||||
|
||||
repo.findAll()
|
||||
.stream()
|
||||
.forEach((it) -> result.getEntities()
|
||||
.add(map2entity(edmEntitySet, it)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Entity map2entity(EdmEntitySet edmEntitySet, Object entry) {
|
||||
|
||||
EntityType<?> et = emf.getMetamodel()
|
||||
.entity(entry.getClass());
|
||||
|
||||
|
||||
Entity e = new Entity();
|
||||
try {
|
||||
// First, we set the entity's primary key
|
||||
|
||||
// Now map all properties
|
||||
et.getDeclaredSingularAttributes().stream()
|
||||
.forEach( (attr) -> {
|
||||
if ( !attr.isAssociation()) {
|
||||
Object v = getPropertyValue(entry,attr.getName());
|
||||
Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v);
|
||||
e.addProperty(p);
|
||||
|
||||
if ( attr.isId()) {
|
||||
e.setId(createId(edmEntitySet.getName(),v));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new ODataRuntimeException("[E141] Unable to create OData entity", ex);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
private Object getPropertyValue(Object entry, String name) {
|
||||
try {
|
||||
return PropertyUtils.getProperty(entry,name);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
private URI createId(String entitySetName, Object id) {
|
||||
try {
|
||||
return new URI(entitySetName + "(" + String.valueOf(id) + ")");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new ODataRuntimeException("[E177] Unable to create URI", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import org.baeldung.examples.olingo4.domain.CarMaker;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CarMakerRepository extends JpaRepository<CarMaker, Long>, JpaSpecificationExecutor<CarMaker>, EdmEntityRepository {
|
||||
|
||||
public default String getEdmEntityName() { return CarMaker.class.getSimpleName();}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import org.baeldung.examples.olingo4.domain.CarModel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CarModelRepository extends JpaRepository<CarModel, Long>, JpaSpecificationExecutor<CarModel>,EdmEntityRepository {
|
||||
|
||||
public default String getEdmEntityName() { return CarModel.class.getSimpleName();}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
public interface EdmEntityRepository {
|
||||
|
||||
public String getEdmEntityName();
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RepositoryRegistry {
|
||||
|
||||
private Map<String,JpaRepository<?,?>> repositoriesByClassName = new HashMap<>();
|
||||
|
||||
public RepositoryRegistry(List<EdmEntityRepository> allRepositories) {
|
||||
|
||||
allRepositories.stream().forEach((r) ->
|
||||
repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository<?,?>)r));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JpaRepository<?, ?> getRepositoryForEntity(EdmEntityType entityType) {
|
||||
JpaRepository<?, ?> repo = repositoriesByClassName.get(entityType.getName());
|
||||
return repo;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
spring:
|
||||
jpa:
|
||||
show-sql: true
|
||||
open-in-view: false
|
||||
hibernate:
|
||||
ddl-auto: update
|
|
@ -0,0 +1,12 @@
|
|||
insert into car_maker(id,name) values (1,'Special Motors');
|
||||
insert into car_maker(id,name) values (2,'BWM');
|
||||
insert into car_maker(id,name) values (3,'Dolores');
|
||||
|
||||
insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018);
|
||||
insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008);
|
||||
|
||||
insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008);
|
||||
insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009);
|
||||
insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008);
|
||||
|
||||
alter sequence hibernate_sequence restart with 100;
|
|
@ -0,0 +1,16 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class Olingo4SampleApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue