我对DDD存储库模式了解不多,但Spring中的实现让我很困惑.
public interface PersonRepository extends JpaRepository<Person, Long> { … }
Run Code Online (Sandbox Code Playgroud)
当接口扩展JpaRepository(或MongoDBRepository ...)时,如果从一个db更改为另一个db,则还必须更改接口.
对我来说,接口是为了提供一些抽象,但在这里并不是那么抽象......
你知道为什么Spring-Data会这样吗?
spring domain-driven-design repository-pattern nosql spring-data
题.如何使用Spring Data REST避免n + 1查询?
背景.在查询Spring Data REST以获取资源列表时,每个生成的顶级资源都具有指向关联资源的链接,而不是将关联资源直接嵌入顶级资源中.例如,如果我查询数据中心列表,则关联的区域显示为链接,如下所示:
{
"links" : [ {
"rel" : "self",
"href" : "http://localhost:2112/api/datacenters/1"
}, {
"rel" : "datacenters.DataCenter.region",
"href" : "http://localhost:2112/api/datacenters/1/region"
} ],
"name" : "US East 1a",
"key" : "amazon-us-east-1a"
}
Run Code Online (Sandbox Code Playgroud)
然而,非常典型的是,想要获得相关信息而不必进行n + 1次查询.为了坚持上面的例子,我可能想要在UI中显示数据中心及其相关区域的列表.
我试过的.我在my上创建了一个自定义查询,RegionRepository以获取给定数据中心键集的所有区域:
@RestResource(path = "find-by-data-center-key-in")
Page<Region> findByDataCentersKeyIn(
@Param("key") Collection<String> keys,
Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
遗憾的是,此查询生成的链接与上面的数据中心查询生成的链接不重叠.以下是我为自定义查询获得的链接:
http://localhost:2112/api/regions/search/find-by-data-center-key-in?key=amazon-us-east-1a&key=amazon-us-east-1b
{
"links" : [ ],
"content" : [ {
"links" : [ {
"rel" : "self",
"href" : "http://localhost:2112/api/regions/1"
}, { …Run Code Online (Sandbox Code Playgroud) 我用的是:
org.springframework.data.mongodb.repository.MongoRepository
Run Code Online (Sandbox Code Playgroud)
我从一个空数据库开始,_id = 1234例如创建一个对象,然后设置一些其他字符串字段hello,然后执行:
repository.save(object);
Run Code Online (Sandbox Code Playgroud)
一切都很好,它将文档保存在MondoDB中.
我创建一个NEW对象,设置相同,_id = 1234但将另一个String字段设置为world,然后另一个保存:
repository.save(newObject);
Run Code Online (Sandbox Code Playgroud)
结果:保存工作但更新原始对象.
预期的结果:这应该失败,DuplicateKeyException因为它_id是唯一的,我在进行每次保存时使用2个单独的对象.
春天的缺陷还是我做错了什么?
是否可以直接指定projection何时调用数据存储库方法?这是存储库代码 - 注意我不想通过REST公开它,而是希望能够从服务或控制器中调用它:
@RepositoryRestResource(exported = false)
public interface UsersRepository extends PagingAndSortingRepository<User, Long> {
@Query(value = "SELECT u FROM User u WHERE ....")
public Page<User> findEmployeeUsers(Pageable p);
}
Run Code Online (Sandbox Code Playgroud)
然后在控制器中我这样做:
@PreAuthorize(value = "hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users/employee")
public Page<User> listEmployees(Pageable pageable) {
return usersRepository.findEmployeeUsers(pageable);
}
Run Code Online (Sandbox Code Playgroud)
有没有什么方法来指定projection的findEmployeeUsers,当它被称为直接像上面的方法?
我意识到上面的代码对于某些人来说可能看起来很奇怪......可以通过REST公开存储库并将其放入@PreAuthorize存储库中.思想控制器是进行安全检查的最佳位置 - 测试更自然,更简单.
那么,可以projection以某种方式将事物传递到直接调用的存储库方法中吗?
我认为这是一个非常基本的问题 -
关于这个错误有几种问题,但前5个结果中没有一个会增加Spring的细微差别.
我有一个在春天写的REST-ful webapp的开头.我正在尝试将其连接到数据库.
我有一个名为Workspace的实体,我正在尝试使用bean的弹簧注入(正确的术语?)来保存工作区实体的实例
package com.parrit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.parrit.models.Workspace;
import com.parrit.models.WorkspaceRepository;
@RestController
@RequestMapping("/workspace")
public class WorkspaceController {
@Autowired
private final WorkspaceRepository repository;
@RequestMapping(method = RequestMethod.POST)
void save( @RequestBody String workspaceHTML) {
Workspace ws = new Workspace();
ws.setHTML(workspaceHTML);
repository.save(ws);
}
}
Run Code Online (Sandbox Code Playgroud)
我的错误在于存储库变量private final WorkspaceRepository repository.编译器抱怨它可能没有被初始化并且尝试运行应用程序会产生相同的结果.
如何将此存储库对象的实例添加到控制器中以对其执行保存操作?
所以我正在使用这个小的Angular + Java + Spring Boot + MongoDB应用程序.它最近得到了很多动作(阅读:代码修改),但数据访问类基本上没有被触及的AFAIK.
然而,似乎MongoRepository突然决定停止持续改变我save()对DB 的更改.
检查mongod.log这是我在save()工作时看到的:
2018-04-11T15:04:06.840+0200 I COMMAND [conn6] command pdfviewer.bookData command: find { find: "bookData", filter: { _id: "ID_1" }, limit: 1, singleBatch: true } planSummary: IDHACK keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:1 nreturned:1 reslen:716 locks:{ Global: { acquireCount: { r: 4 } }, Database: { acquireCount: { r: 2 } }, Collection: { acquireCount: { r: 2 } } } protocol:op_query 102ms
2018-04-11T17:30:19.615+0200 …Run Code Online (Sandbox Code Playgroud) 我正在读"用于Web应用程序的专业Java - Nicholas S. Williams"这本书的例子有Spring Data JPA的这个配置:
@Bean
public DataSource customerSupportDataSource()
{
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource("jdbc/CustomerSupport");
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
properties.put("hibernate.ejb.use_class_enhancer", "true");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
LocalContainerEntityManagerFactoryBean factory =
new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.customerSupportDataSource());
factory.setPackagesToScan("com.wrox.site.entities",
"com.wrox.site.converters");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setLoadTimeWeaver(this.loadTimeWeaver); // TODO: remove when SPR-10856 fixed
factory.setJpaPropertyMap(properties);
return factory;
}
@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject()
);
}
Run Code Online (Sandbox Code Playgroud)
但我一直在使用XML进行配置,我无法弄清楚如何将其转换为XML,到目前为止我已经知道了
<jee:jndi-lookup id="myDataSource" jndi-name="java:comp/env/jdbc/test"/>
<bean id="transactionManager" …Run Code Online (Sandbox Code Playgroud) 我有一个带有Spring Data JPA(hibernate后端)存储库类的Spring Boot应用程序.我添加了一些自定义查找器方法,其中一些具有特定@Query注释,以告诉它如何获取数据.我已经为hibernate二级缓存设置了EhCache,但到目前为止,我可以获得这些结果缓存的唯一方法是启用hibernate查询缓存.我更喜欢定义一个特定的缓存并将实际的域对象存储在那里,就像它是一个普通的查找程序一样.以下是我的回购代码:
public interface PromotionServiceXrefRepository extends PagingAndSortingRepository<PromotionServiceXref, Integer> {
@Query("SELECT psx FROM Customer c " +
"JOIN c.customerProductPromotions cpp " +
"JOIN cpp.productPromotion pp " +
"JOIN pp.promotion p JOIN p.promotionServiceXrefs psx " +
"WHERE c.customerId = ?1")
@QueryHints(@QueryHint(name = "org.hibernate.cacheable", value = "true"))
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "promotionServiceXrefByCustomerId")
Set<PromotionServiceXref> findByCustomerId(int customerId);
}
Run Code Online (Sandbox Code Playgroud)
这里是我定义的"promotionServiceXrefByCustomerId"缓存,它没有被使用:
<cache name="promotionServiceXrefByCustomerId" overflowToDisk="true" diskPersistent="true"
maxEntriesLocalHeap="3000000" eternal="true" diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LFU"
transactionalMode="off" statistics="true">
</cache>
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?如果我启用,StandardQueryCache则此数据将缓存在那里,而hibernate不会执行查询.但是当我禁用查询缓存时,这不会被缓存.我在这做错了什么?请帮忙!
我有一个JPA @MappedSuperClass并@Entity扩展它:
@MappedSuperclass
public class BaseClass {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private Boolean active;
//getters & setters
}
@Entity
public class Worker extends BaseClass{
@Column
private String name;
//getters & setters
}
Run Code Online (Sandbox Code Playgroud)
active基类的字段是子实体的标志.应该只在应用程序中加载活动的.然后我写了一个通用的Spring Data Proxy接口:
public interface Dao<T extends BaseClass, E extends Serializable> extends
CrudRepository<T, E> {
Iterable<T> findByActive(Boolean active);
}
Run Code Online (Sandbox Code Playgroud)
这个是应该用于Worker数据访问的接口,正确扩展前一个:
@Transactional
public interface WorkerDao extends Dao<Worker, Long>{}
Run Code Online (Sandbox Code Playgroud)
好吧,现在在我的逻辑层中,我实现了一个抽象类,它将为我的实体包装CRUD操作的公共代码.我将为每个人提供服务,但我只想继承这个服务abstract.我想为每个服务连接特定的存储库,并使用abstract方法将其提供给超类.这就是我的超类的实现方式:
public abstract …Run Code Online (Sandbox Code Playgroud) 是否可以使用Hibernate和Mysql ReactiveCrudRepository代替CrudRepository?我已经尝试过使用Spring Data Jpa和Hibernate的一些示例,但无法使其工作.我只能ReactiveCrudRepository为MongoDB和cassandra找到一些样本.
spring-data ×10
spring ×6
java ×5
hibernate ×2
mongodb ×2
spring-boot ×2
ehcache ×1
generics ×1
jpa ×1
nosql ×1
reactive ×1
rest ×1
spring-mvc ×1
xml ×1