从Hibernate / Spring数据中的双向一对多关系中获取数据

时间:2016-07-11 08:07:34

标签: java spring hibernate

按照在线发布的有关如何在Hibernate中创建双向一对多关系的说明或教程,我能够创建两个实体类:

@Entity
@Table(name = "user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Column(name = "user_name",nullable = false)
private String userName;

@Column(name="password",nullable = false)
private String password;

@OneToMany (mappedBy = "user",cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<BlogPost> blogPostSet;

//getters and setters

}

@Entity
@Table(name = "blog_post")
public class BlogPost {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Column(nullable = false)
private String title;

@Column(nullable = false)
private String content;

@ManyToOne
@JoinColumn(name ="user_id")
private User user;

//getters and setters
}

我能够在这两个实体上插入数据,但是当我尝试获取数据时会发生递归并导致堆栈溢出错误,请参阅附带的屏幕截图。在这种休眠关系中获取数据的正确方法是什么?

enter image description here

3 个答案:

答案 0 :(得分:0)

映射似乎很好,可能你已经在两个实体中重写了toString()方法,打印出彼此的关系引用,如

package com.example.user.mangoair11;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by User on 6/29/2016.
 */
public class Login extends Activity {

    private EditText editTextEmail;
    private EditText editTextPassword;

    public static final String EMAIL_NAME = "EMAIL";

    String email;
    String password;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_activity);

        editTextEmail = (EditText) findViewById(R.id.editTextEmail);
        editTextPassword = (EditText) findViewById(R.id.editTextPassword);
    }

    public void invokeLogin(View view){
        email = editTextEmail.getText().toString();
        password = editTextPassword.getText().toString();

        login(email,password);

    }

    private void login(final String username, String password) {

        class LoginAsync extends AsyncTask<String, Void, String> {

            private Dialog loadingDialog;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loadingDialog = ProgressDialog.show(Login.this, "Please wait", "Loading...");
            }

            @Override
            protected String doInBackground(String... params) {
                String email = params[0];
                String pass = params[1];

                InputStream is = null;
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("email", email));
                nameValuePairs.add(new BasicNameValuePair("password", pass));
                String result = null;

                try{
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpPost httpPost = new HttpPost(
                            "http://hostogen.com/mangoair10/login.php");
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                    HttpResponse response = httpClient.execute(httpPost);

                    HttpEntity entity = response.getEntity();

                    is = entity.getContent();

                    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 8);
                    StringBuilder sb = new StringBuilder();

                    String line = null;
                    while ((line = reader.readLine()) != null)
                    {
                        sb.append(line + "\n");
                    }
                    result = sb.toString();
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return result;
            }

            @Override
            protected void onPostExecute(String result) {
                String s = result.trim();
                loadingDialog.dismiss();
                if (s.equalsIgnoreCase("success")) {
                    Intent intent = new Intent(Login.this, UserProfile.class);
                    intent.putExtra(EMAIL_NAME, email);
                    finish();
                    startActivity(intent);
                } else {
                    Toast.makeText(getApplicationContext(), "Invalid User Name or Password", Toast.LENGTH_LONG).show();
                }

            }
        }

        LoginAsync la = new LoginAsync();
        la.execute(username, password);

    }


    @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_main, menu);
        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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

MainActivity.java
package com.example.user.mangoair11;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;

 public class MainActivity extends AppCompatActivity {

    Button register,login;
    TextView privacy, contact, about;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        register=(Button)findViewById(R.id.button_register);
        login=(Button)findViewById(R.id.button_login);
        privacy=(TextView)findViewById(R.id.textView2_privacy);
        contact=(TextView)findViewById(R.id.textView3_contact);
        about=(TextView)findViewById(R.id.textView_about);

        register.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent i = new Intent(MainActivity.this, Register.class);
                startActivity(i);
            }
        });

        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent i=new Intent(MainActivity.this,Login.class);
                startActivity(i);
            }
        });

      privacy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent i=new Intent(MainActivity.this,Privacy.class);
                startActivity(i);
            }
        });

        contact.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent i=new Intent(MainActivity.this,Contact.class);
                startActivity(i);
            }
        });

        about.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent i=new Intent(MainActivity.this,About.class);
                startActivity(i);
            }
        });

       }


    @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_main, menu);
        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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }[it give error at page shown in image][1]

        return super.onOptionsItemSelected(item);
    }
}

因此调用彼此toString()会导致stackoverflow错误。

答案 1 :(得分:0)

您必须更改这两个类的toString()方法,以便它不会递归。通过改变它你可以自己打印你想要的东西,这样它就不会进入递归。

答案 2 :(得分:0)

由于两个实体都将id作为字段名称,因此您必须指定@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =“id”),它将解决此问题。