2017-04-11 118 views
3

我有一個帶有註釋的抽象類@MappedSuperClass。大約有15個實體擴展了這個抽象類(在數據庫中有15個對應的表)。這15個實體都具有從抽象超類繼承的相同屬性。彈簧數據庫中的JPA繼承

我已經創建了一個庫,如下爲抽象類:

@NoRepositoryBean 
public interface AbstractRepository <T extends AbstractClass, E extends Serializable> 
            extends PagingAndSortingRepository<T, Serializable> { 
    .....some methods here 
} 

的15個實體/表存儲一些數據(與15個單獨的設備的數據)。根據所選設備,將檢索該表中的數據。我是否必須爲15個具體實體創建15個獨立的存儲庫,或者是否有任何方法可以僅使用抽象存儲庫獲取選定設備的特定實體?如果需要爲每個具體實體創建存儲庫,如何爲特定設備調用獲取正確的存儲庫? (將表名和存儲庫類存儲在應用程序啓動時創建的映射中)?

回答

1

您必須爲每個類創建存儲庫。但是,您可以保留抽象的方法。您需要在每種方法上提供@Query,並使用SpeL(Spring表達式語言)將該類型添加到查詢中。

@NoRepositoryBean 
public interface AbstractRepository 
     extends CrudRepository<T extends AbstractEquipment,Long>{ 

@Query("select e from #{#entityName} as e from equipment where e.name = equipmentName") 
T findEquipmentByName(String equipmentName); 

} 

然後延長像下面

@Transactional 
public interface SpecialEquipmentRepo extends AbstractRepository<SpecialEquipment,Long>{ 

} 
+0

感謝@約瑟夫的澄清。由於需要創建每個設備的存儲庫,因此爲特定設備獲取存儲庫實例的更好方法是什麼?一種方法是自動裝載所有15個存儲庫,並根據傳遞的設備使用正確的存儲庫實例(類似於工廠返回正確的存儲庫) –

+0

我會避免使用交換機,因爲必須維護交換機,你可以'@ Autowire'一個映射,其中鍵是類型,值是存儲庫類型。 –

2

理想的情況下,以下設置應工作:

實體類

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class Equipment { ... } 

@Entity 
public class Crane extends Equipment {} 

@Entity 
public class Excavator extends Equipment {} 

庫接口

public interface EquipmentRepository<T extends Equipment> extends CrudRepository<T> {} 

庫消費者

@Service 
public class SomeService { 
    @Autowired 
    private EquipmentRepository<Crane> craneRepository; 

    @Autowired 
    private EquipmentRepository<Excavator> excavatorRepository; 
} 

我已成立了一個樣本項目on Github來證明這一點。如果運行Maven測試,將顯示通過測試以證明設置按預期工作。

mvn test -Dspring.profiles.active="default,eclipselink" 

mvn test -Dspring.profiles.active="default,openjpa" 

這就是說,這個設置可能無法與Hibernate,這是我懷疑你使用的工作。 Hibernate不支持帶有TABLE_PER_CLASS繼承的自動遞增標識符列。因此,試圖用Hibernate來運行上面的設置會引發異常。這可以通過對上面鏈接的示例運行以下驗證。

mvn test -Dspring.profiles.active="default,hibernate"