2012-03-03 10 views
23

मैं जानना चाहता हूं कि EclipseLink के साथ जेपीए 2 में temporal tables को कैसे कार्यान्वित किया जाए। अस्थायी रूप से मेरा मतलब सारणी है जो वैधता अवधि को परिभाषित करती है।जेपीए का उपयोग कर एक अस्थायी तालिका को कैसे कार्यान्वित करें?

मुझे एक समस्या का सामना करना पड़ रहा है कि रेफरेंसिंग टेबलों में संदर्भित सारणी की प्रकृति की वजह से संदर्भित तालिकाओं (टेम्पोरल टेबल) में विदेशी कुंजी बाधाएं नहीं हो सकती हैं, जो अब उनकी प्राथमिक कुंजी में वैधता अवधि शामिल है।

  • मैं अपनी संस्थाओं के रिश्तों को कैसे मैप करूं?
  • क्या इसका मतलब यह होगा कि मेरी संस्थाओं के पास उन वैध समय इकाइयों के साथ कोई रिश्ता नहीं हो सकता है?
  • क्या उन रिश्तों को शुरू करने की उत्तरदायित्व अब मेरे द्वारा किसी प्रकार की सेवा या विशेष डीएओ में मैन्युअल रूप से करनी चाहिए?

मुझे मिली एकमात्र चीज है जो DAO Fusion नामक एक ढांचा है जो इससे संबंधित है।

  • क्या इसे हल करने के कोई अन्य तरीके हैं?
  • क्या आप इस विषय के बारे में एक उदाहरण या संसाधन प्रदान कर सकते हैं (अस्थायी डेटाबेस के साथ जेपीए)?

यहां डेटा मॉडल और इसकी कक्षाओं का एक काल्पनिक उदाहरण है।

1 परिदृश्य:: गैर टेम्पोरल मॉडल

डेटा मॉडल: Non Temporal Data Model

टीम:

यह एक सरल मॉडल लौकिक पहलुओं से निपटने के लिए यह नहीं है कि के रूप में शुरू होता है
@Entity 
public class Team implements Serializable { 

    private Long id; 
    private String name; 
    private Integer wins = 0; 
    private Integer losses = 0; 
    private Integer draws = 0; 
    private List<Player> players = new ArrayList<Player>(); 

    public Team() { 

    } 

    public Team(String name) { 
     this.name = name; 
    } 


    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQTEAMID") 
    @SequenceGenerator(name="SEQTEAMID", sequenceName="SEQTEAMID", allocationSize=1) 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @Column(unique=true, nullable=false) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Integer getWins() { 
     return wins; 
    } 

    public void setWins(Integer wins) { 
     this.wins = wins; 
    } 

    public Integer getLosses() { 
     return losses; 
    } 

    public void setLosses(Integer losses) { 
     this.losses = losses; 
    } 

    public Integer getDraws() { 
     return draws; 
    } 

    public void setDraws(Integer draws) { 
     this.draws = draws; 
    } 

    @OneToMany(mappedBy="team", cascade=CascadeType.ALL) 
    public List<Player> getPlayers() { 
     return players; 
    } 

    public void setPlayers(List<Player> players) { 
     this.players = players; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Team other = (Team) obj; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     return true; 
    } 


} 

प्लेयर:

@Entity 
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"team_id","number"})}) 
public class Player implements Serializable { 

    private Long id; 
    private Team team; 
    private Integer number; 
    private String name; 

    public Player() { 

    } 

    public Player(Team team, Integer number) { 
     this.team = team; 
     this.number = number; 
    } 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQPLAYERID") 
    @SequenceGenerator(name="SEQPLAYERID", sequenceName="SEQPLAYERID", allocationSize=1) 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @ManyToOne 
    @JoinColumn(nullable=false) 
    public Team getTeam() { 
     return team; 
    } 

    public void setTeam(Team team) { 
     this.team = team; 
    } 

    @Column(nullable=false) 
    public Integer getNumber() { 
     return number; 
    } 

    public void setNumber(Integer number) { 
     this.number = number; 
    } 

    @Column(unique=true, nullable=false) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((number == null) ? 0 : number.hashCode()); 
     result = prime * result + ((team == null) ? 0 : team.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Player other = (Player) obj; 
     if (number == null) { 
      if (other.number != null) 
       return false; 
     } else if (!number.equals(other.number)) 
      return false; 
     if (team == null) { 
      if (other.team != null) 
       return false; 
     } else if (!team.equals(other.team)) 
      return false; 
     return true; 
    } 


} 

टेस्ट वर्ग:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"/META-INF/application-context-root.xml"}) 
@Transactional 
public class TestingDao { 

    @PersistenceContext 
    private EntityManager entityManager; 
    private Team team; 

    @Before 
    public void setUp() { 
     team = new Team(); 
     team.setName("The Goods"); 
     team.setLosses(0); 
     team.setWins(0); 
     team.setDraws(0); 

     Player player = new Player(); 
     player.setTeam(team); 
     player.setNumber(1); 
     player.setName("Alfredo"); 
     team.getPlayers().add(player); 

     player = new Player(); 
     player.setTeam(team); 
     player.setNumber(2); 
     player.setName("Jorge"); 
     team.getPlayers().add(player); 

     entityManager.persist(team); 
     entityManager.flush(); 
    } 

    @Test 
    public void testPersistence() { 
     String strQuery = "select t from Team t where t.name = :name"; 
     TypedQuery<Team> query = entityManager.createQuery(strQuery, Team.class); 
     query.setParameter("name", team.getName()); 
     Team persistedTeam = query.getSingleResult(); 
     assertEquals(2, persistedTeam.getPlayers().size()); 

     //Change the player number 
     Player p = null; 
     for (Player player : persistedTeam.getPlayers()) { 
      if (player.getName().equals("Alfredo")) { 
       p = player; 
       break; 
      } 
     } 
     p.setNumber(10);   
    } 


} 

अब आप की कैसे टीम और खिलाड़ी तो तुम क्या करने की जरूरत समय की निश्चित बिंदु पर था एक इतिहास रखने के लिए कहा जाता है जोड़ने के लिए है प्रत्येक तालिका के लिए एक अवधि का समय जो ट्रैक करना चाहता है। तो चलिए इन अस्थायी कॉलम जोड़ें। हम सिर्फ Player के साथ शुरू करने जा रहे हैं।

2 परिदृश्य: टेम्पोरल मॉडल

डेटा मॉडल: Temporal Data Model

आप देख सकते हैं हम प्राथमिक कुंजी ड्रॉप और एक और एक है कि दिनांक (अवधि) भी शामिल है परिभाषित करने के लिए किया था। इसके अलावा हमें अनूठी बाधाओं को छोड़ना पड़ा क्योंकि अब उन्हें मेज में दोहराया जा सकता है। अब तालिका में मौजूदा प्रविष्टियां और इतिहास भी हो सकता है।

चीजें बहुत बदसूरत हो जाती हैं अगर हमें टीम अस्थायी बनाना पड़ता है, तो इस मामले में हमें विदेशी कुंजी बाधा को छोड़ना होगा कि Player तालिका Team है। समस्या यह है कि आप जावा और जेपीए में इसे कैसे मॉडल करेंगे।

ध्यान दें कि आईडी एक सरोगेट कुंजी है। लेकिन अब सरोगेट कुंजियों को तारीख शामिल करनी है क्योंकि यदि वे ऐसा नहीं करते हैं तो यह एक ही इकाई (टाइमलाइन के दौरान) एक से अधिक "संस्करण" स्टोर करने की अनुमति नहीं देगा।

+0

1) आपने किस टूल के साथ चित्र खींचा? 2) एक अस्थायी आयाम आपकी आवश्यकताओं के लिए पर्याप्त है, डीओओफ़्यूजन पैटर्न और मेरा उत्तर (इन पैटर्नों के आधार पर) मेरी राय 3 में अधिक है) क्या आप ऐसे समाधान को प्राथमिकता देते हैं जो प्लेयर को अस्थायी पहलू जोड़ता है या आप पसंद करते हैं यह दोनों टेबल 4) आपका अंतिम अनुच्छेद गलत है। एक सरोगेट कुंजी में कभी भी अतिरिक्त फ़ील्ड शामिल नहीं होंगे। उस स्थिति में आपके पास दो सरोगेट कुंजी होगी। – ChrLipp

+0

@ChrLipp 1) स्पार्क्स एंटरप्राइज़ आर्किटेक्ट 2) मैं सहमत हूं। 3) मुझे एक समाधान की आवश्यकता है जो दोनों तालिकाओं में अस्थायी जोड़ता है। 4) मैं सहमत नहीं हूं कि एक सरोगेट कुंजी नहीं है। मुझे लगता है कि यह एक सरोगेट कुंजी है क्योंकि: 1. अस्थायी कॉलम जोड़ने से पहले यह एक सरोगेट कुंजी थी जो व्यावसायिक अर्थ के साथ एक कुंजी नहीं थी।उदाहरण के लिए प्लेयर की व्यावसायिक कुंजी "team_id" और "संख्या" है और टीम से "नाम" है। दोनों में अपनी खुद की सरोगेट कुंजी "आईडी" होती है जब उनके पास अस्थायी कॉलम नहीं होते थे। समस्या यह है कि जब मैं अस्थायी कॉलम जोड़ता हूं जो अब काम नहीं करता है। एक ही प्रविष्टि एक ही तालिका में एक से अधिक बार प्रकट हो सकती है। –

+0

यही कारण है कि सरोगेट कुंजी "आईडी" अब केवल एक कॉलम नहीं हो सकती है क्योंकि यह एक ही प्रविष्टि है लेकिन विभिन्न समय-सारिणी में ट्रैक की जाती है, ताकि एक ही प्रविष्टि को एक से अधिक बार प्रदर्शित करने की अनुमति दी जा सके। एक प्राथमिक कुंजी "आईडी + वैधता" या "आईडी + मान्य" या "आईडी + वैध प्रारंभ + वैध" के रूप में निम्नलिखित। मैंने जावा मैपिंग्स पर सुविधा के लिए आखिरी विकल्प चुना है, जहां मेरे पास एक "अंतराल" ऑब्जेक्ट है जो एक अवधि को परिभाषित करता है, इसलिए जेपीए में इसे मैप करने के लिए मैंने आईडी को "अंतराल" को एम्बेडेड आईडी के रूप में जोड़ा। –

उत्तर

7

मैं बहुत हूँ दिलचस्पी मैं एन इस विषय। मैं अब कई वर्षों से काम कर रहा हूं जो इन पैटर्नों का उपयोग करते हैं, यह विचार जर्मन डिप्लोमा थीसिस से हमारे मामले में आया था।

मुझे "डीएओ फ्यूजन" ढांचे को नहीं पता था, वे इस जानकारी को प्रदान करने के लिए धन्यवाद, दिलचस्प जानकारी और लिंक प्रदान करते हैं। विशेष रूप से pattern page और aspects page बहुत अच्छे हैं!

अपने प्रश्नों के लिए: नहीं, मैं अन्य साइटों, उदाहरणों या ढांचे को इंगित नहीं कर सकता। मुझे डर है कि आपको या तो डीएओ फ्यूजन फ्रेमवर्क का उपयोग करना होगा या इस कार्यक्षमता को अपने आप से कार्यान्वित करना होगा। आपको यह समझना होगा कि आपको किस प्रकार की कार्यक्षमता की ज़रूरत है। "डीएओ फ्यूजन" ढांचे के संदर्भ में बात करने के लिए: क्या आपको "वैध अस्थायी" और "रिकॉर्ड अस्थायी" दोनों की आवश्यकता है? रिकॉर्ड अस्थायी राज्यों में जब आपके डेटाबेस पर परिवर्तन लागू होता है (आमतौर पर ऑडिटिंग मुद्दों के लिए उपयोग किया जाता है), वैध अस्थायी राज्य जब वास्तविक जीवन में परिवर्तन हुआ था या वास्तविक जीवन में वैध है (एप्लिकेशन द्वारा उपयोग किया जाता है) जो रिकॉर्ड अस्थायी से भिन्न हो सकता है। ज्यादातर मामलों में एक आयाम पर्याप्त होता है और दूसरा आयाम की आवश्यकता नहीं होती है।

वैसे भी, अस्थायी कार्यक्षमता आपके डेटाबेस पर प्रभाव डालती है। जैसा कि आपने कहा था: "जो अब उनकी प्राथमिक कुंजी में वैधता अवधि शामिल है"। तो आप एक इकाई की पहचान कैसे मॉडल करते हैं? मैं surrogate keys का उपयोग पसंद करता हूं। उस मामले में इसका मतलब है: इकाई डेटाबेस में वस्तु (पंक्ति)

  • अस्थायी स्तंभों के लिए
  • एक आईडी के लिए

    • एक आईडी

    तालिका के लिए प्राथमिक कुंजी ऑब्जेक्ट आईडी है।प्रत्येक इकाई में एक तालिका में एक या अधिक (1-n) प्रविष्टियां होती हैं, जिसे ऑब्जेक्ट आईडी द्वारा पहचाना जाता है। तालिकाओं के बीच लिंक इकाई आईडी पर आधारित है। चूंकि अस्थायी प्रविष्टियां डेटा की मात्रा को गुणा करती हैं, इसलिए मानक संबंध काम नहीं करते हैं। एक मानक 1-एन संबंध x * 1-y * n संबंध बन सकता है।

    आप इसे कैसे हल करते हैं? मानक दृष्टिकोण मैपिंग टेबल पेश करना होगा, लेकिन यह स्वाभाविक रूप से दृष्टिकोण नहीं है। सिर्फ एक टेबल को संपादित करने के लिए (उदाहरण के लिए। निवास परिवर्तन होता है) आपको मैपिंग टेबल को अपडेट/डालना होगा जो प्रत्येक प्रोग्रामर के लिए अजीब है।

    अन्य दृष्टिकोण मैपिंग टेबल का उपयोग नहीं करना होगा। इस मामले में आप रेफरेंसियल अखंडता और विदेशी कुंजी का उपयोग नहीं कर सकते हैं, प्रत्येक तालिका अलग-अलग अभिनय कर रही है, एक टेबल से दूसरे को जोड़ने के लिए मैन्युअल कार्यान्वित किया जाना चाहिए, न कि जेपीए कार्यक्षमता के साथ।

    डेटाबेस ऑब्जेक्ट्स को प्रारंभ करने की कार्यक्षमता ऑब्जेक्ट्स (डीएओ फ़्यूज़न फ्रेमवर्क में) के भीतर होना चाहिए। मैं इसे एक सेवा में नहीं रखूंगा। यदि आप इसे डीएओ में देते हैं या सक्रिय रिकॉर्ड पैटर्न का उपयोग करते हैं तो आप पर निर्भर है।

    मुझे पता है कि मेरा जवाब आपको "उपयोग करने के लिए तैयार" ढांचे प्रदान नहीं करता है। आप एक बहुत ही जटिल क्षेत्र में हैं, मेरे अनुभव संसाधनों से इस उपयोग परिदृश्य में खोजने के लिए बहुत मुश्किल है। आपके प्रश्न के लिए धन्यवाद! लेकिन वैसे भी मुझे उम्मीद है कि मैंने आपकी डिजाइन में आपकी मदद की है।

    इस जवाब आप संदर्भ पुस्तक "एसक्यूएल में विकास समय उन्मुख डेटाबेस अनुप्रयोग" मिलेगा ही, देखें https://stackoverflow.com/a/800516/734687

    अद्यतन: उदाहरण

    • प्रश्न: मान लीजिए कि मैं एक है कि चलो व्यक्ति तालिका जिसमें सरोगेट कुंजी है जो "आईडी" नामक फ़ील्ड है। इस बिंदु पर प्रत्येक संदर्भ तालिका में "आईडी" एक विदेशी कुंजी बाधा के रूप में होगी। अगर मैं अब अस्थायी कॉलम जोड़ता हूं तो मुझे प्राथमिक कुंजी को "id + from_date + to_date" में बदलना होगा। प्राथमिक कुंजी बदलने से पहले मुझे प्रत्येक संदर्भ तालिका के प्रत्येक विदेशी बाधा को इस संदर्भित तालिका (व्यक्ति) में छोड़ना होगा। क्या मैं सही हू? मेरा मानना ​​है कि सरोगेट कुंजी के साथ आपका क्या मतलब है। आईडी एक जेनरेट की गई कुंजी है जिसे अनुक्रम द्वारा उत्पन्न किया जा सकता है। व्यक्ति तालिका की व्यावसायिक कुंजी एसएसएन है।
    • उत्तर: बिल्कुल नहीं। एसएसएन एक प्राकृतिक कुंजी होगी, जिसे मैं objcet पहचान के लिए उपयोग नहीं करता हूं। इसके अलावा "id + from_date + to_date" composite key होगा, जिसे मैं भी टालना चाहूंगा। यदि आप example पर देखते हैं तो आपके पास दो टेबल, व्यक्ति और निवास होगा और हमारे उदाहरण के लिए हमारे पास एक विदेशी कुंजी निवास के साथ 1-एन संबंध है। अब हम प्रत्येक तालिका पर अस्थायी फ़ील्ड जोड़ रहे हैं। हां हम हर विदेशी कुंजी बाधा छोड़ देते हैं। व्यक्ति को उस आईडी पर एक इंडेक्स के साथ पंक्ति की पहचान करने के लिए एक आईडी मिलेगी (इसे ROW_ID कहते हैं), एक आईडी व्यक्ति को पहचानने के लिए (इसे ENTIDY_ID कहते हैं)। व्यक्ति के लिए वही। बेशक आपका दृष्टिकोण भी काम करेगा, लेकिन उस स्थिति में आपके पास ऐसे ऑपरेशन होंगे जो ROW_ID को बदलते हैं (जब आप एक समय अंतराल बंद करते हैं), जिसे मैं टालना चाहूंगा।

    example ऊपर मान्यताओं (2 टेबल, 1-एन) के साथ लागू विस्तार करने के लिए:

    • एक प्रश्न डेटाबेस में सभी प्रविष्टियों को दिखाने के लिए (सभी वैधता जानकारी और रिकॉर्ड - उर्फ ​​तकनीकी - जानकारी शामिल):

      SELECT * FROM Person p, Residence r 
      WHERE p.ENTITY_ID = r.FK_ENTITY_ID_PERSON   // JOIN
    • रिकॉर्ड - उर्फ ​​तकनीकी - जानकारी को छिपाने के लिए एक प्रश्न। यह सभी वैधता-संस्थाओं के परिवर्तन दिखाता है।

      SELECT * FROM Person p, Residence r 
      WHERE p.ENTITY_ID = r.FK_ENTITY_ID_PERSON AND 
      p.recordTo=[infinity] and r.recordTo=[infinity] // only current technical state
    • वास्तविक मान दिखाने के लिए एक प्रश्न।

      SELECT * FROM Person p, Residence r 
      WHERE p.ENTITY_ID = r.FK_ENTITY_ID_PERSON AND 
      p.recordTo=[infinity] and r.recordTo=[infinity] AND 
      p.validFrom <= [now] AND p.validTo > [now] AND  // only current valid state person 
      r.validFrom <= [now] AND r.validTo > [now]   // only current valid state residence

    आप देख सकते हैं मैं ROW_ID का उपयोग कभी नहीं। समय पर वापस जाने के लिए [अब] एक टाइमस्टैम्प के साथ बदलें।

    एक "PlaysInTeam" तालिका परिचय दें:: अगर आपके अपडेट
    मैं सिफारिश करेंगे निम्न डेटा मॉडल को प्रतिबिंबित करने के

    अद्यतन

    • आईडी
    • आईडी दल (विदेशी कुंजी टीम के लिए)
    • आईडी प्लेयर (प्लेयर के लिए विदेशी कुंजी)
    • ValidFrom
    • ValidTo

    जब आप एक टीम आप तारीख, जिस के लिए संबंध वैध है और [ValdFrom, ValidTo)

    में होना टीम अस्थायी मैं बनाने के लिए है के साथ क्वेरी करने के लिए है के खिलाड़ियों की सूची दो दृष्टिकोण हैं;

    दृष्टिकोण 1: एक "सीजन" तालिका का परिचय जो मॉडल एक के मौसम के लिए एक वैधता

    • आईडी
    • सीजन नाम (उदाहरण के लिए ग्रीष्मकालीन 2011।)
    • (शायद आवश्यक नहीं से, क्योंकि हर एक जानता है जब मौसम है)
    • करने के लिए (शायद आवश्यक नहीं
    • , क्योंकि हर एक जानता है जब मौसम है)

    टीम टेबल विभाजित करें। आपके पास ऐसे क्षेत्र होंगे जो टीम से संबंधित हैं और जो समय प्रासंगिक (नाम, पता, ...) और फ़ील्ड नहीं हैं जो मौसम के लिए प्रासंगिक समय (जीत, हानि, ..) हैं। उस मामले में मैं टीम और टीम इनसेसन का उपयोग करूंगा। PlaysInTeam टीम के बजाय TeamInSeason को लिंक कर सकते हैं (पर विचार किया जाना है - मैं इसे टीम को इंगित करते हैं)

    TeamInSeason

    • आईडी
    • आईडी टीम
    • आईडी सीजन
    • जीत
    • हानि
    • ...

    दृष्टिकोण 2: मौसम को स्पष्ट रूप से मॉडल न करें। टीम टेबल विभाजित करें। आपके पास ऐसे क्षेत्र होंगे जो टीम से संबंधित हैं और जो समय प्रासंगिक नहीं हैं (नाम, पता, ...) और फ़ील्ड जो समय प्रासंगिक हैं (जीत, हानि, ..)। उस मामले में मैं टीम और टीम इंटरवल का उपयोग करूंगा। टीम इंटरवल में अंतराल के लिए "से" और "से" फ़ील्ड होंगे।

  • PlaysInTeam टीम के बजाय TeamInterval से लिंक कर सकता है (मैं इस पर टीम दिया जाएगा)

    TeamInterval

    • आईडी
    • आईडी टीम
    • से
    • करने के लिए
    • जीत
    • घटाने
    • ...

    दोनों दृष्टिकोणों में: यदि आपको किसी भी समय प्रासंगिक क्षेत्र के लिए अलग टीम टेबल की आवश्यकता नहीं है, तो विभाजित न करें।

    +0

    मान लें कि मेरे पास एक व्यक्तिगत तालिका है जिसमें एक सरोगेट कुंजी है जो "आईडी" नामक एक फ़ील्ड है। इस बिंदु पर प्रत्येक संदर्भ तालिका में "आईडी" एक विदेशी कुंजी बाधा के रूप में होगी। अगर मैं अब अस्थायी कॉलम जोड़ता हूं तो मुझे प्राथमिक कुंजी को "id + from_date + to_date" में बदलना होगा। प्राथमिक कुंजी बदलने से पहले मुझे प्रत्येक संदर्भ तालिका के प्रत्येक विदेशी बाधा को इस संदर्भित तालिका (व्यक्ति) में छोड़ना होगा। क्या मैं सही हू? मेरा मानना ​​है कि सरोगेट कुंजी के साथ आपका क्या मतलब है। आईडी एक जेनरेट की गई कुंजी है जिसे अनुक्रम द्वारा उत्पन्न किया जा सकता है। व्यक्ति तालिका की व्यावसायिक कुंजी एसएसएन है। –

    +0

    ने हमारी टिप्पणियों के साथ उत्तर अपडेट किया। – ChrLipp

    1

    ऐसा लगता है कि आप इसे जेपीए के साथ नहीं कर सकते क्योंकि यह मानता है कि तालिका-नाम और संपूर्ण स्कीमा स्थिर है।

    सबसे अच्छा विकल्प (डीएओ पद्धति का उपयोग कर उदाहरण के लिए)

    यदि प्रदर्शन, मुद्दा है जब तक कि हम रिकॉर्ड करोड़ों के बारे में बात कर रहे हैं JDBC के माध्यम से यह करने के लिए हो सकता है, मुझे शक है कि गतिशील रूप से कक्षाएं बनाने & इसे संकलित & तब लोड करना यह बेहतर होगा।

    एक और विकल्प विचारों का उपयोग कर सकता है (यदि आपको जेपीए का उपयोग करना चाहिए) किसी भी तरह सारणी सारणी हो सकती है (@Entity (name = "myView") को मानचित्र करें, तो आपको दृश्य को गतिशील रूप से अपडेट/प्रतिस्थापित करना होगा में बना सकते हैं या prefix_sessionId

    से REPLACE देखें usernameView के रूप में चुनें * उदाहरण के लिए यदि आप एक दृश्य लिख सकता है कहने के लिए:

    if (EVENT_TYPE = 'crear_tabla' AND ObjectType = 'tabla ' && ObjectName starts with 'userName') then CREATE OR REPLACE VIEW userNameView AS SELECT * FROM ObjectName //the generated table.

    आशा है कि यह मदद करता है (espero कुए ते ayude)

    2

    बिल्कुल सही नहीं है कि आपका क्या मतलब है, लेकिन EclipseLink के इतिहास के लिए पूर्ण समर्थन है। आप @DescriptorCustomizer के माध्यम से क्लासडिस्क्रिप्टर पर HistoryPolicy सक्षम कर सकते हैं।

    +2

    अंतर यह है कि अस्थायी दृष्टिकोण इतिहास तालिका की बजाय एक तालिका के साथ काम करता है और ग्रहण लिंक केवल दो के बजाय एक आयाम का समर्थन करता है। लेकिन वैसे भी, जानकारी के लिए धन्यवाद। मुझे यह सुविधा नहीं पता था। – ChrLipp

    1

    DAO Fusion में, दोनों समयरेखा (वैधता और रिकॉर्ड अंतराल) में एक इकाई को ट्रैक करना उस इकाई को BitemporalWrapper द्वारा लपेटकर महसूस किया जाता है।

    bitemporal reference documentation नियमित Order इकाई BitemporalOrder इकाई द्वारा लिपटे एक उदाहरण प्रस्तुत करता है। प्रत्येक तालिका पंक्ति के लिए BitemporalOrder वैधता और रिकॉर्ड अंतराल के कॉलम के साथ, Order (@ManyToOne के माध्यम से) के लिए विदेशी कुंजी संदर्भ के साथ एक अलग डेटाबेस तालिका में मानचित्र।

    प्रलेखन यह भी इंगित करता है कि प्रत्येक बिटमोरल रैपर (उदा। BitemporalOrder) बिटमोरल रिकॉर्ड श्रृंखला के भीतर एक आइटम का प्रतिनिधित्व करता है। इसलिए, आपको कुछ उच्च स्तरीय इकाई की आवश्यकता है जिसमें बिटकैम्पल रैपर संग्रह शामिल है, उदा। Customer इकाई जिसमें @OneToMany Collection<BitemporalOrder> orders शामिल है।

    इसलिए, यदि आप एक "तार्किक बच्चे" इकाई की जरूरत है (Order जैसे या Player) bitemporally ट्रैक किया जाए, और अपने "तार्किक जनक" इकाई (जैसे Customer या Team) bitemporally रूप में अच्छी तरह से ट्रैक किया जाता है, तो आप प्रदान करने की आवश्यकता दोनों के लिए bitemporal wrappers। आपके पास BitemporalPlayer और BitemporalTeam होगा। BitemporalTeam@OneToMany Collection<BitemporalPlayer> players घोषित कर सकते हैं। लेकिन ऊपर उल्लिखित अनुसार @OneToMany Collection<BitemporalTeam> teams रखने के लिए आपको कुछ उच्च स्तरीय इकाई की आवश्यकता है। उदाहरण के लिए, आप Game इकाई बना सकते हैं जिसमें BitemporalTeam संग्रह शामिल है।

    हालांकि, अगर आपको रिकॉर्ड अंतराल की आवश्यकता नहीं है और आपको केवल वैधता अंतराल की आवश्यकता है (उदाहरण के लिए बिटमैपोरल नहीं, लेकिन आपकी इकाइयों की अस्थायी ट्रैकिंग), तो आपकी सबसे अच्छी शर्त अपने स्वयं के कस्टम कार्यान्वयन को रोल करना है।

    संबंधित मुद्दे