Hibernate选择具有给定属性的集合元素

时间:2016-06-09 19:01:04

标签: hibernate hql

实体package bikurim.silverfix.com.bikurim; import android.app.SearchManager; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.support.v7.widget.SearchView; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import java.util.ArrayList; import bikurim.silverfix.com.bikurim.adapters.MenuDrawerAdapter; import bikurim.silverfix.com.bikurim.adapters.RecyclerViewAdapter; import bikurim.silverfix.com.bikurim.items.FamilyItem; public class MainActivity extends AppCompatActivity { private ArrayList<FamilyItem> families = new ArrayList<FamilyItem>(); private ArrayList<bikurim.silverfix.com.bikurim.items.MenuItem> items = new ArrayList<bikurim.silverfix.com.bikurim.items.MenuItem>(); private DrawerLayout drawerLayout; private ActionBarDrawerToggle drawerToggle; private RecyclerView recyclerView, menuView; private RecyclerViewAdapter adapter; private MenuDrawerAdapter navAdapter; private SearchView searchView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_families); // Setting up the tool bar final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); // Setting up the main lists and their adapters fillList(); createMenuItems(); recyclerView = (RecyclerView) findViewById(R.id.rv); menuView = (RecyclerView) findViewById(R.id.right_drawer); adapter = new RecyclerViewAdapter(families); navAdapter = new MenuDrawerAdapter(items); // Default Animator DefaultItemAnimator animator = new DefaultItemAnimator(); recyclerView.setItemAnimator(animator); menuView.setItemAnimator(animator); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); menuView.setLayoutManager(new LinearLayoutManager(this)); menuView.setAdapter(navAdapter); Log.d("Menu Items Count:", ""+navAdapter.getItemCount()); // Setting up the navigation drawer side-menu with DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close) { /** Called when a drawer is in closed state. */ public void onDrawerClosed(View view) { super.onDrawerClosed(view); getSupportActionBar().setTitle(R.string.app_name); } /** Called when a drawer is in open state. */ public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getSupportActionBar().setTitle(R.string.drawer_name); } }; drawerLayout.addDrawerListener(drawerToggle); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Does absolutly nothing, yet!", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL); } private void fillList() { families.add(new FamilyItem("Ohayon", "12:36")); families.add(new FamilyItem("Zohar", "14:23")); families.add(new FamilyItem("Lasry", "15:55")); families.add(new FamilyItem("Zambuzak", "17:45")); families.add(new FamilyItem("Cohen", "11:33")); families.add(new FamilyItem("Tapera", "09:25")); families.add(new FamilyItem("Ochuya", "09:25")); families.add(new FamilyItem("Konichiwua", "09:25")); families.add(new FamilyItem("Kontaktiwa", "09:25")); } private void createMenuItems() { items.add(new bikurim.silverfix.com.bikurim.items.MenuItem(R.drawable.about, "עזרה")); items.add(new bikurim.silverfix.com.bikurim.items.MenuItem(R.drawable.settings, "הגדרות")); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); drawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); drawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_families, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName())); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { adapter.getFilter().filter(query); return true; // handled } @Override public boolean onQueryTextChange(String newText) { adapter.getFilter().filter(newText); return true; } }); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (drawerToggle.onOptionsItemSelected(item)) { return true; } //noinspection SimplifiableIfStatement if (id == R.id.action_search) { return true; } return super.onOptionsItemSelected(item); } } 的集合属性Project与实体contributors的{​​{1}}关系映射

@OneToMany

然后我需要先检查User是否已@Entity @Table( name = "projects" ) public class Project { ... @OneToMany @JoinTable(name = "project_contributors") private List<User> contributors = new ArrayList<User>(); ... } contributors user,然后再添加id。我正在尝试使用HQL查询,但我显然非常感兴趣。

我在尝试什么:

contributorId

但它给出了错误

Query query = session.createQuery(
        "select p.contributors from Project p where p.id = :pId and p.contributors.id = :cId"
    );

query.setParameter("pId", projectId);
query.setParameter("cId", contributorId);

@SuppressWarnings("unchecked")
List<User> res = (List<User>) query.list();

有没有一个好的撒玛利亚人想给我一点推力?

我做的另一次尝试是

illegal attempt to dereference collection [project0_.id.contributors] with element property reference [id]

但没有。

2 个答案:

答案 0 :(得分:15)

contributors是一个集合。因此,它没有名为id的属性。

Id是此Collection的元素的属性。

您可以通过加入集合而不是取消引用它来解决问题:

SELECT p 
  FROM Project pj 
  JOIN pj.contributors  p 
 WHERE pj.id       = :pId
   AND p.Id     = :cId

答案 1 :(得分:2)

有助于读取您的HQL,就好像是Java代码试图取消引用Java类中的字段一样:

p.contributors.id

您正在尝试访问id p.contributors List<User>。列表没有ID。这样就行不通了。

select p.contributors

这样的查询,如果正确的话,将返回一个贡献者列表的列表。这不是你想要的。

你会在SQL中做到这一点?加入。与JPQL相同:

select c from Project p
join p.contributors c
where p.id = :pId and c.id = :cId

进行连接并为其分配别名允许查询关联的目标实体。